I have created a Settings class wrapper around QSettings that provides the following methods for access in QML:
Q_INVOKABLE void setValue(Key key, const QVariant &newValue);
Q_INVOKABLE QVariant value(Key key);
In the user interface, there are CheckBox instances that look like this:
CheckBox {
checked: Settings.value(Settings.KeySomeBoolSettings)
}
QSettings loads boolean values into QVariant as a QString type as "true" or "false" (which is fine). The problem is when QML converts this implicitly to a boolean expression as needed by the checked property, it is always converting to true (even if it is actually "false"). I've found a workaround to detect whenever a QVariant in Settings::value() is actually a boolean.
QVariant Settings::value(Key key)
{
QVariant value = mSettings->value(stringNameForKey(key), mDefaultValues[key]);
//this block is the workaround
if (QString(value.typeName()) == "QString" &&
(value.toString() == "false" || value.toString() == "true"))
return QVariant(value.toBool());
return value;
}
When detected, the actual QVariant returned is QVariant(value.toBool()) which causes the internal type to actually be bool. So when the internal type is bool, then QML can make the implicit conversion fine. From what I can tell, QML is taking the varient literally as a string, and then converting that to a bool which is always true unless the string is blank. Is this a bug, or am I doing something wrong?
As described in ECMAScript language specification, converting to boolean return false, if value is +0, -0, null, false, NaN, undefined, or the empty string. All other values, including any object or the string "false", converted to true.
Also, in QML you can use Qt Labs Settings QML Type instead of wrapper around QSettings
Related
For my GUI I have a class to add more functionality to Gtk::Entries. In that class I have a protected boolean variable. I have functions built to adjust the boolean variable to be true or false when it needs to be, this works no problem. When I try to pass that boolean value is where the problem occurs
For instance what did not work is:
((Gtk::Entry *)w)->signal_activate().connect(sigc::bind<Gtk::Widget *>(sigc::mem_fun(*this, &Dialog::function), w2));
The Dialog::function looks like this:
void Dialog::function(Gtk::Widget *w2)
{
if((MyClass *) this)->get_boolean_val())
w2->do_something();
}
Whenver I did this the boolean value would always come back false, even after varifying that the class variable would change. I proved that by editing the above as such.
((Gtk::Entry *)w)->signal_activate().connect(sigc::bind<Gtk::Widget *, Gtk::Entry *>(sigc::mem_fun(*this, &Dialog::function), w2, w));
and changing the function body to this:
void Dialog::function(Gtk::Widget *w2, Gtk::Entry *w)
{
if((MyClass *) w)->get_boolean_val())
w2->do_something();
}
This works but I feel as if there is a better way to edit the 'w' object's boolean value and pull it. Similar to how the keyword 'this' works.
I'm new to C++
How to convert QVariant to QJsonValue?
I know QVariant provide the toJsonValue function, but it did not perform as expected.
For example:
qDebug()<<QVariant(1.0).toJsonValue();
qDebug()<<QVariant("test").toJsonValue();
Both return:
QJsonValue(null)
QJsonValue(null)
Expect output:
QJsonValue(double, 1)
QJsonValue(string, "test")
You can use this static function too:
QJsonValue::fromVariant( myVariant )
Check this link for more info.
You might do the following:
QVariant dblVariant(1.0);
QVariant strVariant("test");
QJsonValue dblJs(dblVariant.toDouble());
QJsonValue strJs(strVariant.toString());
Your approach doesn't work because variant object should have user type QJsonValue, but it doesn't. Therefore it returns default constructed QJsonValue object.
Hello everyone I am trying to get to know pointers better and I stumbled into a Qt type change. I have made a QString array and gave the pointer to the array to a method. But when I try to use a QString functions it give a error and says that it is a QCharRef which does not have the member function isEmpty().
The code:
QString data_array[2][3] =
{
{"11:28:8","Room 1","Presence detected"},
{"11:38:8","Room 1","No presence"}
}
bool method(QString *_data_array)
{
QString *data_array = _data_array;
return data_array[0][1].isEmpty(); /* changed to QCharRef */
}
My question is why does this happen and how can I prevent it or change it?
The reason for which you are getting QCharRef is due to how QString is built. The [] operator returns one character from a QString (QString is built up from QChars, much like strings in C/C++ are character arrays). From the Qt documentation:
The return value is of type QCharRef, a helper class for QString. When you get an object of type QCharRef, you can use it as if it were a QChar &. If you assign to it, the assignment will apply to the character in the QString from which you got the reference.
So what that means for you is that when you use the lovely square bracket operators, you are no longer using a QString, you are using a QChar reference.
As for how to change it, QChar's isNull() seems like it would fit your uses. so instead try return data_array[0][1].isNull(); and that should work.
I would also look into QStringList if you're doing things with lists of strings
I made a function which returns a QString. At some points in my function it should return an empty QString.
Just returning "" doesn't work. When I use QString::isEmpty() it's not.
My "emergency plan" was to return an "empty" string and check with it whether the text is "empty". But I don't think that's good style.
So how do I return an empty QString?
The idiomatic way to create an empty QString is using its default constructor, i.e. QString(). QString() creates a string for which both isEmpty() and isNull() return true.
A QString created using the literal "" is empty (isEmpty() returns true) but not null (isNull() returns false).
Both have a size()/length() of 0.
According to the QString docs, returning "" should work; as should returning QString().
Try printing out the string you are testing to make sure it's really empty:
printf("xxx [%s]\n", myStr.toUtf8().constData());
This is a follow up to a previous question: Qt ActiveX
I am trying to use an ActiveX control in my program.
QAxWidget* mAX = new QAxWidget();
mAX->setControl("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");
I know that there is a function like the one below (used getDocumentation()):
SendCommand(QString input, QString& output)
But when I try to execute it:
QString returString;
mAX->dynamicCall("SendCommand(QString,QString&)","something",returnString);
I always get:
returString = "";
I searched the web and saw a similar bug which was reported on their bug tracker. It does not seem fixed yet:
Calling functions through dynamicCall() don't return values by QVariant
Also a post where someone seems to have the same problem:
QAxObject and dynamicCall
Anybody know of a solution/work around ?
EDIT:
The original function is SendCommand(LPCTSTR command,BSTR* ret).
Maybe an issue with the way the BSTR* is handled as a &QString ?
you can use this solution
QString strRetVal;
QVariant returnValue("");
QVariant param1("something");
QList<QVariant> inplist;
inplist<<param1;
inplist<<returnValue;
mAX->dynamicCall("SendCommand(QString,QString&)",inplist );
strRetVal=inplist.at(1).toString();
From looking at the documentation, you are not calling the function correctly. You are passing in a QString, yet the function takes a QVariant. Since QVariant doesn't have explicit constructors (by design), a temporary QVariant is created and passed to dynamicCall. As a consequence your returnValue doesn't get updated.
QVariant dynamicCall( const char * function, const QVariant & var1 = QVariant(), ...
, const QVariant & var8 = QVariant() )
I think that everything will work when you use a QVariant instead.
QVariant returnValue;
mAX->dynamicCall("SendCommand(QString,QString&)", "something", returnValue );