从 QThread 影响 QDialog
Posted
技术标签:
【中文标题】从 QThread 影响 QDialog【英文标题】:Affecting a QDialog From A QThread 【发布时间】:2013-02-12 22:57:51 【问题描述】:我想从一个单独的线程影响一个 QDialog,我必须做两件事:
dialog->show();
dialog->raise();
dialog->activateWindow();
据我了解,这些是事件,因此必须在主线程事件循环中完成。我想我在QThread::run()
中使用QApplication::postEvent
实现了这一点。谁能确认一下?
其次,我想显示在该单独线程中处理的图像。我想我需要子类化我的对话框类并编写一个线程安全的setImage()
函数,然后由paintEvent()
调用......但是,这似乎是不可能的。我不能用QMutex::unlock()
阻止paintEvent?谁能提供一些建议?
QApplication::postEvent(dialog, new QShowEvent());
不起作用。
这是从单独的线程调用槽(作为函数)的解决方案:
QMetaObject::invokeMethod(dialog, "show", Qt::QueuedConnection);
QMetaObject::invokeMethod(dialog, "raise", Qt::QueuedConnection);
...仍在开发activateWindow()
和QThread
安全功能。
所以对于QImage
,它是一个QPaintDevice。据说它是线程安全的。我的方法是在线程中设置一个类成员QImage
。然后再画。
请注意,下面的方法同样好,即使不是更好。
【问题讨论】:
我会避免将对话框指针传递给线程,而是连接来自另一个线程中 QObject 的信号。对于 activateWindow,您需要编写自己的插槽,只调用 activateWindow()。 嘿弗兰克,有什么特别的原因吗?另外,为了确认,您是说在QThread::run()
中使用emit SIGNAL
而不是使用invokeMethod
。在 QThread 的构建过程中,SIGNAL 已经正确连接到哪里?
【参考方案1】:
我认为这是一种更清晰的方式来做你想做的事:
class Dialog : public QDialog
...
public slots:
void showImage(QImage img);
...
void Dialog::showImage(QImage img);
setImage(img);
show();
raise();
activateWindow();
class Thread : public QThread
...
signals:
void imageReady(QImage);
void Thread::run()
QImage img;
/// image processing stuff
emit imageReady(img);
...
Thread *thread = new Thread;
Dialog *dialog = new Dialog;
connect(thread, SIGNAL(imageReady(QImage)), dialog, SLOT(showImage(QImage)));
thread->start();
【讨论】:
以上是关于从 QThread 影响 QDialog的主要内容,如果未能解决你的问题,请参考以下文章