我想从一个单独的线程影响QDialog,我必须做两件事:
dialog->show();
dialog->raise();
dialog->activateWindow();
据我所知,这些是事件,因此必须在主线程事件循环中完成。我想我是通过QApplication::postEvent
内的QThread::run()
实现此目标的。任何人都可以确认吗?
其次,我想显示在该单独的线程中处理的图像。我想我需要继承我的对话框类并编写一个线程安全setImage()
函数,然后由paintEvent()
调用...但是,这似乎是不可能的。我无法使用QMutex::unlock()
阻止paintEvent?有人可以提供一些建议吗?
QApplication::postEvent(dialog, new QShowEvent());
无效。
这是从单独的线程调用slot(作为函数)的解决方案:
QMetaObject::invokeMethod(dialog, "show", Qt::QueuedConnection);
QMetaObject::invokeMethod(dialog, "raise", Qt::QueuedConnection);
...仍在使用activateWindow()
和QThread
安全功能。
因此对于QImage
,它是一个QPaintDevice。据说它是线程安全的。我的方法是在线程中设置一个类成员QImage
。然后画了。
注意,虽然不是更好,但下面的方法同样好。
答案 0 :(得分:4)
我认为这是一种更清晰的方式来做你想做的事情:
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();