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