13 qt qt4 signals-slots
我是QT的新手,我正在做一些学习.
我想触发一个从C++线程(目前是Qthread)修改GUI小部件的插槽.
不幸的是我得到了:ASSERTION失败了:Q_ASSERT(qApp && qApp-> thread()== QThread :: currentThread());
这是一些代码:
(MAIN + Thread类)
class mythread : public QThread
{
public:
mythread(mywindow* win){this->w = win;};
mywindow* w;
void run()
{
w->ui.textEdit->append("Hello"); //<--ASSERT FAIL
//I have also try to call a slots within mywindow which also fail.
};
};
int main(int argc, char *argv[])
{
QApplication* a = new QApplication(argc, argv);
mywindow* w = new mywindow();
w->show();
mythread* thr = new mythread(w);
thr->start();
return a->exec();
}
Run Code Online (Sandbox Code Playgroud)
窗口:
class mywindow : public QMainWindow
{
Q_OBJECT
public:
mywindow (QWidget *parent = 0, Qt::WFlags flags = 0);
~mywindow ();
Ui::mywindow ui;
private:
public slots:
void newLog(QString &log);
};
Run Code Online (Sandbox Code Playgroud)
所以我很好奇如何在不同的线程中通过代码更新gui部分.
谢谢你的帮助
Mar*_*utz 17
stribika几乎是对的:
QMetaObject::invokeMethod( textEdit, "append", Qt::QueuedConnection,
Q_ARG( QString, myString ) );
Run Code Online (Sandbox Code Playgroud)
但是,cjhuitt是正确的:您通常希望在线程上声明一个信号并将其连接到append()插槽,以免费获得对象生命周期管理(嗯,对于次要接口更改的代价).在旁注中,附加论点:
Qt::QueuedConnection ); // <-- This option is important!
Run Code Online (Sandbox Code Playgroud)
来自cjhuitt的答案是不再需要的(在Qt <= 4.1中),因为connect()默认情况下Qt::AutoConnection现在(Qt> = 4.2)做正确的事情并在排队和直接连接模式之间切换并且基于QThread::currentThread()线程亲和力接收器QObject在发射时间(而不是发送器和接收器在连接时的亲和力).
除了stribika的答案,我经常发现使用信号/插槽连接更容易.您可以在连接时指定它应该是排队连接,以避免线程信号出现在其拥有对象的上下文中.
class mythread : public QThread
{
signals:
void appendText( QString );
public:
mythread(mywindow* win){this->w = win;};
mywindow* w;
void run()
{
emit ( appendText( "Hello" ) );
};
};
int main(int argc, char *argv[])
{
QApplication* a = new QApplication(argc, argv);
mywindow* w = new mywindow();
w->show();
mythread* thr = new mythread(w);
(void)connect( thr, SIGNAL( appendText( QString ) ),
w->ui.textEdit, SLOT( append( QString ) ),
Qt::QueuedConnection ); // <-- This option is important!
thr->start();
return a->exec();
}
Run Code Online (Sandbox Code Playgroud)
您需要使用QMetaObject :: invokeMethod.例如:
void MyThread::run() {
QMetaObject::invokeMethod(label, SLOT(setText(const QString &)), Q_ARG(QString, "Hello"));
}
Run Code Online (Sandbox Code Playgroud)
(上面的代码来自这里:http://www.qtforum.org/article/26801/qt4-threads-and-widgets.html)
| 归档时间: |
|
| 查看次数: |
20892 次 |
| 最近记录: |