02-22-2013 06:16 PM
How can I compare the color of a label in QML to another Color. My code below does not work as I'd expect it to. Despite the "scoreLabel" having color "Color.DarkGray" the if statements returns true.
I also tried comparing it to the Color.create() color, but that does not work as expected either.
if(scoreLabel.textStyle.color != Color.DarkGray/*Color.create("#f89e52")*/){
scoreLabel.textStyle.color = Color.DarkGray;
//Otherwise make it orange.
} else {
scoreLabel.textStyle.color = Color.create("#f89e52")
}
Solved! Go to Solution.
02-22-2013 06:43 PM
They do seem to be of the same type, in any case. When I log them I get this:
console.log(scoreLabel.textStyle.color); console.log(Color.DarkGray);
outputs:
QVariant(bb::cascades::Color) QVariant(bb::cascades::Color)
02-22-2013 06:50 PM - edited 02-22-2013 06:59 PM
Could you please try:
if (scoreLabel.textStyle.color.toString() != Color.DarkGray.toString())
But most likely this won't work.
I've checked Color class source code and there are operator== and operator!= defined. I don't think QML can use them though. It seems all instances are wrapped in QVariants which can't be directly compared.
And Color class doesn't seem to support a conversion to string, so comparing them as strings also won't work.
A possible solution is creating a C++ function and exporting it to QML:
Q_INVOKABLE bool colorsEqual(Color *color1, Color *color2)
{
return *color1 == *color2;
}
UPD: Color is declared as meta-type in Cascades headers but pointer to it is not:
resources/color.h:Q_DECLARE_METATYPE(bb::cascades:
If the above function won't work, try the following:
Q_INVOKABLE bool colorsEqual(const Color &color1, const Color &color2)
{
return color1 == color2;
}
...or...
Q_INVOKABLE bool colorsEqual(Color color1, Color color2)
...
Try experimenting with different forms, I'm not sure which one will work.
02-22-2013 07:03 PM
if(scoreLabel.textStyle.color.toString() == Color.DarkGray.toString())
this seems to always return true, strangely. I will try the C++ solution and see how that works. I would imagine it will work, seems like a good solution.
02-22-2013 07:11 PM
02-22-2013 07:21 PM - edited 02-22-2013 07:21 PM
I can't get any of the equals methods working.
Error: Unknown method parameter type: Color
for the second two and
Error: Unknown method parameter type: Color*
for the first one.
I'll have to look into propertys, I guess. There's no way to change a property at runtime, is there? I'm not sure I can do all my logic with just a single state.
For instance, if the label starts black and has state1 when an action is performed I need to switch it to color orange. Orange would be state2. Now If I need to reset that back to black I still have the state assigned to it indicating that the color is black, since I couldn't change the state to state2.
Any ideas?
I'm starting to think it might be quicker to rewrite the entire list in C++ -__- QML is nothing but trouble.
02-22-2013 08:20 PM - edited 02-22-2013 08:57 PM
I'll try to experiment with C++ function exporting too.
The following code seems to work:
// Navigation pane project template
import bb.cascades 1.0
Page {
Container {
Label {
id: label
textStyle { base: style1.style }
text: "Label text"
}
Button {
id: button
text: "Click me"
property variant activeStyle: style1
onClicked: {
if (activeStyle == style1) {
label.textStyle.base = style2.style
activeStyle = style2
} else {
label.textStyle.base = style1.style
activeStyle = style1
}
}
}
attachedObjects: [
TextStyleDefinition {
id: style1
color: Color.create("#ff0000")
},
TextStyleDefinition {
id: style2
color: Color.create("#00ff00")
}
]
}
}
Directly swapping the colors should also work. Properties can be reassigned at runtime.
Ok, the C++ method also works. But I think the one with states is better.
QML:
// Navigation pane project template
import bb.cascades 1.0
Page {
Container {
Label {
id: label
textStyle { color: Color.create("#ff0000") }
text: "Label text"
}
Button {
id: button
text: "Click me"
onClicked: {
if (app.colorsEqual(label.textStyle.color, Color.create("#ff0000"))) {
label.textStyle.color = Color.create("#00ff00")
} else {
label.textStyle.color = Color.create("#ff0000")
}
}
}
}
}
Test.hpp:
#include <bb/cascades/Color>
class Test : public QObject { Q_OBJECT public: Test(bb::cascades::Application *app); virtual ~Test() {} Q_INVOKABLE bool colorsEqual(bb::cascades::Color color1, bb::cascades::Color color2); };
Test.cpp:
Test::Test(bb::cascades::Application *app)
: QObject(app)
{
...
qml->setContextProperty("app", this); // <--------- ADDED
AbstractPane *root = qml->createRootObject<AbstractPane>();
app->setScene(root);
...
bool Test::colorsEqual(Color color1, Color color2)
{
return color1 == color2;
}
02-23-2013 07:53 PM
I was able to solve my problem with a variant. The reason I thought they couldn't be assigned at run time was because when I tried to conditionally set the variant with an if statement, I got a syntax error. Of course, I might just not know the correct syntax to do it, but this won't work:
property variant activeStyle: if(ListItemData.num == 0) {style1} else {style2}However, by assigning the variant in the onCreationCompleted method of the label, I was able to skirt around that problem.
Thanks for your help!