从QThread影响QDialog

时间:2013-02-12 22:57:51

标签: c++ multithreading qt qthread

我想从一个单独的线程影响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。然后画了。

注意,虽然不是更好,但下面的方法同样好。

1 个答案:

答案 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();