Qt ActiveX dynamicCall return value always empty - c++

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 );

Related

How to convert QVariant to QJsonValue?

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.

QString variable changed to QCharRef when i use pointers in method

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

How to get data back from QVariant for a usertype?

I'm using a QVariant to store a pointer to my object in a QComboBox
void MainFrame::initContainerBox(QComboBox *oBox)
{
IDataContainer *idc = new CSVContainer();
QVariant v(QVariant::UserType, idc);
oBox->addItem(idc->getContainername(), v);
void *idc1 = v.data();
if(idc1 == idc)
printf("Test\n");
}
But how do I get the data back? When I use data() the pointer is different, so this doesn't seem to be correct. From gooogling I had the impression that I have to register a type for each class I want to use in a QVariant is that correct or can I retrieve the value without that?
After two days of googling and trying all kind of combinations I finally found out how to do this. Here is an example using a QComboBox putting an item and getting it back. IDataContainer * is an arbitrary class which is not related to Qt.
Q_DECLARE_METATYPE(IDataContainer *)
void MainFrame::initContainerBox(QComboBox *oBox)
{
IDataContainer *idc = new CSVContainer();
QVariant v;
v.setValue(idc);
oBox->addItem(idc->getContainername(), v);
QVariant v2 = oBox->itemData(oBox->currentIndex());
IDataContainer *idc1 = v2.value<IDataContainer *>();
if(idc1 == idc)
printf("Test\n");
}
So with my first approach of using value() I was on the right track, the only missing bits were how to set the value and using the macro Q_DECLARE_METATYPE(IDataContainer *).
Apparently using the constructor doesn't work, so one has to call setValue() instead. If somebody knows how to use the constructor it would be nice to show it.

is there a method to check if a QJsonObject object contains specific attribute?

there is a QJsonObject
{
"a":"...",
"b":"...",
"c":"..."
}
is there a method to check if this object contains "a"?
You have a few options, according to the documentation:
The most obvious is QJsonObject::contains which returns a bool
You can call QJsonObject::find which will return an iterator. If the item isn't found, the return value will be equal to QJsonObject::end Use this if you need an iterator anyways.
You can call QJsonObject::value, which will return the value for the key if present, and QJsonValue::Undefined otherwise. You're probably using the value method anyways to get the value for a key, so this will allow you to do one lookup instead of two. It may be tempting to use this for a performance boost, but remember that it will be harder to read and in most cases the performance gain is small enough that it's probably not worth it
All of this came directly from the Qt documentation - my favorite thing about Qt is their fantastic documentation, so I encourage you to make that your first stop when you have questions like these.
Right, so in general, Qt uses the API "contains" for such things. If you take a look at the following places, you will see it yourself:
QHash: bool QHash::contains(const Key & key) const
QMap: bool QMap::contains(const Key & key) const
QStringList: bool QStringList::contains(const QString & str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
QString: bool QString::contains(const QString & str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
QList: bool QList::contains(const T & value) const
QVector: bool QVector::contains(const T & value) const
QByteArray: bool QByteArray::contains(const QByteArray & ba) const
Having mentioned all this, you may not be entirely surprised that the requested class have a method called contains as follows:
QJsonObject: bool QJsonObject::contains(const QString & key) const

QVariant to QIcon/QPixmap/QImage

I want to extract a QIcon I've stored in one of a QTreeWidget's columns, as Qt::DecorationRole.
QTreeWidgetItem *item = ui->treeWidget->topLevelItem(index);
const QIcon &icon = item->data(0, Qt::DecorationRole)._howToConvert_();
However, I can only get the data as QVariant, and I could not find a function to convert from a QVariant to QIcon. Is it possible to do it?
OK, found the answer in the docs for QVariant upon further inspection.
This works:
QImage image = variant.value<QImage>();
I find the solution as follows:
QImage name_image = table_store_multi_model_->item(i_row,0)->data(Qt::DecorationRole).value().toImage();
Generally, we read data with data(), but here need a parameter "Qt::DecorationRole";

Categories