Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从QThread影响QDialog_C++_Multithreading_Qt_Qthread - Fatal编程技术网

C++ 从QThread影响QDialog

C++ 从QThread影响QDialog,c++,multithreading,qt,qthread,C++,Multithreading,Qt,Qthread,我想从一个单独的线程影响QDialog,我必须做两件事: dialog->show(); dialog->raise(); dialog->activateWindow(); 据我所知,这些都是事件,因此必须在主线程事件循环中完成。我想我是通过QThread::run()中的QApplication::postEvent实现的。有人能证实吗 第二,我想显示一个在单独线程中处理的图像。我想我需要对dialog类进行子类化,并编写一个线程安全的setImage()函数,然后由pa

我想从一个单独的线程影响QDialog,我必须做两件事:

dialog->show();
dialog->raise();
dialog->activateWindow();
据我所知,这些都是事件,因此必须在主线程事件循环中完成。我想我是通过
QThread::run()
中的
QApplication::postEvent
实现的。有人能证实吗

第二,我想显示一个在单独线程中处理的图像。我想我需要对dialog类进行子类化,并编写一个线程安全的
setImage()
函数,然后由
paintEvent()
调用。。。然而,这似乎是不可能的。我无法使用
QMutex::unlock()
?有人能提供一些建议吗


QApplication::postEvent(对话框,新建QShowEvent())不起作用

这是从单独的线程调用插槽(作为函数)的解决方案:

QMetaObject::invokeMethod(dialog, "show", Qt::QueuedConnection);
QMetaObject::invokeMethod(dialog, "raise", Qt::QueuedConnection);
。。。仍在使用
activateWindow()
QThread
安全函数

因此,对于
QImage
,它是一个Qpaint设备。应该是线程安全的。我的方法是在线程中设置一个类成员
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();

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

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

我会避免将对话框指针传递给线程,而是将来自另一个线程中QObject的信号连接起来。对于activateWindow,您需要编写自己的插槽,只调用activateWindow()。嘿,Frank,有什么特别的原因吗?另外,为了确认,您说的不是在
QThread::run()
中使用
invokeMethod
而是使用
emit SIGNAL
。在构建QThread之前,信号在哪里被正确连接?我会避免将对话框指针传递给线程,而是连接来自另一个线程中QObject的信号。对于activateWindow,您需要编写自己的插槽,只调用activateWindow()。嘿,Frank,有什么特别的原因吗?另外,为了确认,您说的不是在
QThread::run()
中使用
invokeMethod
而是使用
emit SIGNAL
。在构建QThread之前,信号在哪里正确连接?