我是新来QT和我正在做一些学习。
我想触发从一个C ++螺纹(目前的QThread)修改GUI窗口小部件的狭槽。
不幸的是我得到一个:断言失败的:Q_ASSERT(qApp && qApp->线程()==的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();
}
窗口:
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);
};
所以,我在如何通过代码在不同的线程更新GUI部分好奇。
感谢您的帮助
除了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();
}
stribika得到它差不多吧:
QMetaObject::invokeMethod( textEdit, "append", Qt::QueuedConnection,
Q_ARG( QString, myString ) );
cjhuitt的权利,但:你平时想声明的线程上的信号,并将其连接到append()
插槽,以获得对象的生命周期管理的自由(当然,对于一个小接口改变的价格)。 在阿里纳斯的附加参数:
Qt::QueuedConnection ); // <-- This option is important!
从cjhuitt的答案是没有必要再(它是,在Qt的<= 4.1)时,由于connect()
默认为Qt::AutoConnection
现在(QT> = 4.2)做正确的事和排队和直接连接模式之间切换的基于上QThread::currentThread()
和所述接收器的螺纹亲和力QObject
在EMIT时间(而不是在连接时发送者和接收者的亲和力)。
您需要使用QMetaObject :: invokeMethod中 。 例如:
void MyThread::run() {
QMetaObject::invokeMethod(label, SLOT(setText(const QString &)), Q_ARG(QString, "Hello"));
}
(以上代码来自这里: http://www.qtforum.org/article/26801/qt4-threads-and-widgets.html )
我不认为你被允许直接调用的东西,导致从任何其他线程比主线程漆事件。 这将导致崩溃。
我想你可以使用事件循环异步调用的东西,这样的主界面线程拿起,然后做在主线程,这是什么cjhuitt建议更新。
如果我们的线程关联说什么GUI,但我们不是在GUI线程,也不在QThread的?
我的意思是,一个非调质(通知)线程调用一个QObject的接口方法,在此我们发出自动连接信号。 QObject的的主题亲和力主线程,但该过程实际上是从另一个线程调用。 什么会了Qt在这里做?