从Q线程影响Q对话框

Affecting a QDialog From A QThread

本文关键字:对话框 影响 线程      更新时间:2023-10-16

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

请注意,以下方法即使不是更好,也是同样好的。

我认为这是一种更清晰的方式来做你想做的事情:

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