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中的QTimer发出信号,但GUI线程未更新_C++_Multithreading_Qt_User Interface - Fatal编程技术网

C++ QThread中的QTimer发出信号,但GUI线程未更新

C++ QThread中的QTimer发出信号,但GUI线程未更新,c++,multithreading,qt,user-interface,C++,Multithreading,Qt,User Interface,我有两个QMainWindows,其中一个我想隐藏一段时间,同时加载所需的内容,然后显示另一个。当显示另一个图像时,它应通过QTimer定期更改其显示的图像。我设法完成了大部分工作,但即使调用了更新图像的插槽,第二个QMainWindow也没有更新 这是正在加载的窗口类标题: #ifndef LOADINGWINDOW_H #define LOADINGWINDOW_H #include <QMainWindow> #include <QLabel> #include

我有两个QMainWindows,其中一个我想隐藏一段时间,同时加载所需的内容,然后显示另一个。当显示另一个图像时,它应通过QTimer定期更改其显示的图像。我设法完成了大部分工作,但即使调用了更新图像的插槽,第二个QMainWindow也没有更新

这是正在加载的窗口类标题:

#ifndef LOADINGWINDOW_H
#define LOADINGWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QTimer>
#include <QImage>
#include <QVector>
#include <QDebug>
#include <QVBoxLayout>

class LoadingWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit LoadingWindow(QWidget *parent = 0);

public slots:
    void startLoading();
    void stopLoading();

private slots:
    void loadingTimerExpired();

private:
    QLabel *m_loadingLabel;
    QVector<QPixmap> m_loadingPixmaps;
    QTimer *m_loadingTimer;
    int m_currentLoadingImage;
    QThread* m_loadingThread;

};

#endif // LOADINGWINDOW_H

句子没有像我期望的那样工作,GUI线程不知何故被阻塞了。有人知道如何解决这个问题吗?

在这种情况下,在跨线程触发信号时不应该使用Qt::DirectConnection,因为您正在插槽中执行GUI操作。Qt::DirectConnection:。如果我不使用Qt::DirectConnection,我看到插槽loadingTimerExpired在第一个主窗口完成计算之前不会被触发。那么为什么这些计算没有在其他线程中完成?好的。。。是否有任何方法可以使用排队连接或自动连接,并将其优先级设置为立即执行?当然没有。要做到这一点,它需要一个免费的事件循环。主事件循环不应被长时间阻塞。它会导致GUI冻结。
#include "loadingwindow.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QSettings>
#include <QFile>
#include <QThread>

LoadingWindow::LoadingWindow(QWidget *parent)
    : QMainWindow(parent, Qt::WindowStaysOnTopHint | Qt::CustomizeWindowHint | Qt::FramelessWindowHint)
{

    QSettings appSettings("app.ini",  QSettings::IniFormat);
    QString appPath = appSettings.value("appSettings/appPath").toString();
    QFile file(appPath + "/style.qss");
    file.open(QFile::ReadOnly | QFile::Text);
    QTextStream ts(&file);
    qApp->setStyleSheet(ts.readAll());


    m_loadingLabel = new QLabel();
    m_loadingPixmaps = QVector<QPixmap>(N_IMAGES);
    for (int i=0; i<m_loadingImgs.size(); i++)
    {
        m_loadingImgs[i] = QPixmap::fromImage(QImage(":/loadingImg" +
                                  QString::number(i) + ".png").scaled(QSize(800,500), Qt::KeepAspectRatio));
    }

    m_currentLoadingImage = 0;

    m_currentLoadingImage++;
    m_loadingLabel->setUpdatesEnabled(true);
    m_loadingLabel->setAttribute(Qt::WA_TranslucentBackground);
    m_loadingLabel->setPixmap(m_loadingPixmaps[0]);
    m_loadingLabel->adjustSize();
    m_loadingLabel->move(QApplication::desktop()->screen()->rect().center() - m_loadingLabel->rect().center());

    this->setCentralWidget(m_loadingLabel);
    this->adjustSize();
    this->move(QApplication::desktop()->screen()->rect().center() - m_loadingLabel->rect().center());


    m_loadingTimer = new QTimer();
    m_loadingTimer->setInterval(70);
    m_loadingThread = new QThread(this);
    m_loadingTimer->moveToThread(m_loadingThread);
    QObject::connect(m_loadingTimer,
                     SIGNAL(timeout()),
                     this,
                     SLOT(loadingTimerExpired())
                     , Qt::DirectConnection);

    QObject::connect(m_loadingThread,
                     SIGNAL(started()),
                     m_loadingTimer,
                     SLOT(start()));

    QObject::connect(m_loadingThread,
                     SIGNAL(finished()),
                     m_loadingTimer,
                     SLOT(stop()));

}

void LoadingWindow::startLoading()
{
    m_loadingThread->start();
    this->show();
    QApplication::processEvents();
}

void LoadingWindow::stopLoading()
{
    this->hide();
    m_loadingThread->exit();
}


void LoadingWindow::loadingTimerExpired()
{


    m_loadingLabel->setPixmap(m_loadingPixmaps[m_currentLoadingImage]);
    m_loadingLabel->update();
    QApplication::processEvents();

    m_currentLoadingImage++;
    if (m_currentLoadingImage == m_loadingPixmaps.size())
        m_currentLoadingImage=0;
}
m_loadingLabel->update();
QApplication::processEvents();