PDA

View Full Version : QPushButton invoking setText fails



bokadam
25th June 2012, 14:25
I'm trying to set text of a push button by invoking its method via QMetaObject::invokeMethod but failing to achieve any successful results. I have tried it with some other widgets and they seem to work fine. Would appropriate any suggestions, kinda stuck here and googling is not helping. Here is the code:




// w is QMainWindow

QWidget* label = w.findChild<QLabel*>("label");
((QLabel*)label)->setText("text old"); // works fine
bool res_label = QMetaObject::invokeMethod(label, "setText", Q_ARG(QString, "text new")); // works fine, returns true

QWidget* lineEdit = w.findChild<QLineEdit*>("lineEdit");
((QLineEdit*)lineEdit)->setText("text old"); // works fine
bool res_line_edit = QMetaObject::invokeMethod(lineEdit, "setText", Q_ARG(QString, "text new")); // works fine, returns true

QWidget* textBrowser = w.findChild<QTextBrowser*>("textBrowser");
((QTextBrowser*)textBrowser)->setText("text old"); // works fine
bool res_text_browser = QMetaObject::invokeMethod(textBrowser, "setText", Q_ARG(QString, "text new")); // works fine, returns true

QWidget* pushButton = w.findChild<QPushButton*>("pushButton");
((QPushButton*)pushButton)->setText("text old"); // works fine
bool res_push_button = QMetaObject::invokeMethod(pushButton, "setText", Q_ARG(QString, "text new")); // NOT WORKING, RETURNS FALSE



I tried all connection types (Qt::DirectConnection, Qt::QueuedConnection, Qt::BlockingQueuedConnection, Qt::AutoConnection). Also setText is defined as a public slot in the first three widgets but is defined as a public function in the QPushButton, is it possible that it might be the cause of the problem?

yeye_olive
25th June 2012, 15:28
That is right, QMetaObject::invokeMethod() works on signals, slots and invokable methods, not on properties (such as text for QPushButton). For the latter you can use a combination of QMetaObject::indexOfProperty(), QMetaObject::property(), and QMetaProperty::write().

bokadam
25th June 2012, 15:53
Thanks yeye, it worked like a charm. Here is the working code:



QWidget* pushButton = w.findChild<QPushButton*>("pushButton");
int propertyIndex = pushButton->metaObject()->indexOfProperty("text");
QMetaProperty property = pushButton->metaObject()->property(propertyIndex);
bool res = property.write(pushButton, "text new 2"); // works fine, returns true

wysota
25th June 2012, 19:37
That is right, QMetaObject::invokeMethod() works on signals, slots and invokable methods, not on properties (such as text for QPushButton). For the latter you can use a combination of QMetaObject::indexOfProperty(), QMetaObject::property(), and QMetaProperty::write().

Or just QObject::setProperty()

tarry1583
13th September 2012, 12:55
HI ,
Facing an issue for passing a pointer as QARG in invokeMethod :

I am calling the api void CAppManager::launchUrl(const int f_iXcoord,const int f_iYcoord,const int f_iHeight, const int f_iWidth,const QString f_cobjUrl,unsigned long *f_ulRenHandle,bool bSetupURL) as

QMetaObject::invokeMethod(this,"launchUrl",Qt::Que uedConnection,
Q_ARG(int,0),Q_ARG(int,0),Q_ARG(int,480),Q_ARG(int ,800),Q_ARG(QString,sSetUpURL),Q_ARG(unsigned long*,handle),Q_ARG(bool,true));

The issue seems to be with ARG f_ulRenHandle . As when the function had this argument only as pass by value and in InvokeMethod I had passed just Q_ARG(unsigned long,handle) instead of Q_ARG(unsigned long*,handle).It worked.
handle here has to be pointer or refrence as its getting modified in launchURL API .Here I am using pointer as we can't use Refrences with Q_ARG.Here invoke method is always returning 0.
I am initializing/declaring handle as follows :
unsigned long dummyHandle=0;
unsigned long * handle = &dummyHandle;
Please let me know what measure should i take to solve this issue ?

wysota
13th September 2012, 14:20
You should not be passing pointers or references. It is better to use a signal-slot connection that will give you the result.