qt - QT 多线程中 UI 显示的延迟
问题描述
我有一个多线程应用程序。我的应用程序有 2 个对话框:主对话框 ( Dialog1
) 和事务对话框 ( Dialog2
)。当应用程序运行时,Dialog1
会开始QThread
下载一个大文件。下载时Dialog2
会显示。Dialog2
将显示下载状态。请注意,即使Dialog2
显示 ,下载仍将继续。显示时Dialog2
,将启动轮询线程。当检测到卡时,该线程将处理交易。
问题:当检测到卡时,Dialog2
应该更新 UI(我为此使用了信号和插槽)。但是,更新 UI 会延迟。或者需要几秒钟才能向 UI 显示正确的消息。这只发生在下载正在进行时。
下面是我的代码:
对话1:
void Dialog1::startDownlaod()
{
DownloadClass *downloadClass ;
Dialog2 *dialog2 = new Dialog2 (this);
cout << "[Dialog2] from main thread: " << QThread::currentThreadId() << endl;
downloadClass = new DownloadClass ();
pAppDownloadThread_ = nullptr;
pAppDownloadThread_ = new QThread();
downloadClass->moveToThread(pAppDownloadThread_);
connect(pAppDownloadThread_, SIGNAL(started()), downloadClass , SLOT(processDownloadRequest()));
connect(downloadClass , SIGNAL(finished()), pAppDownloadThread_, SLOT(quit()));
connect(downloadClass , SIGNAL(finished()), downloadClass , SLOT(deleteLater()));
connect(pAppDownloadThread_, SIGNAL(finished()), pAppDownloadThread_, SLOT(deleteLater()));
connect(downloadClass , SIGNAL(updateDownloadStatus()), dialog2, SLOT(updateDownloadStatus()));
pAppDownloadThread_->start();
dialog2->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
dialog2->exec();
}
下载器类:
class DownloadClass : public QObject
{
Q_OBJECT
public slots:
void processDownloadRequest();
signals:
void finished();
void onUpdateDownloadStatus();
}
对话2:
// this is the slot that will update downlaod status
void Dialog2::updateDownloadStatus()
{
ui->labelStatus.setText("some text here");
}
// this is method to start the poller thread
void Dialog2::startPollingThread()
{
pollingThread_ = new QThread;
Poller::instance()->moveToThread(pollingThread_); // singleton
connect(pollingThread_, SIGNAL(started()), Poller::instance(), SLOT(poll()));
connect(Notifier::getInstance(), SIGNAL(displayMessage(QString)), this, SLOT(displayMessage(QString)));
connect(Poller::instance(), SIGNAL(finished()), pPollingThread_, SLOT(quit()));
connect(pPollingThread_, SIGNAL(finished()), Poller::instance(), SLOT(deleteLater()));
connect(pPollingThread_, SIGNAL(finished()), pPollingThread_, SLOT(deleteLater()));
cout << "[Dialog2] from main thread: " << QThread::currentThreadId() << endl;
pollingThread_->start();
}
轮询器类:
class Poller : public QObject
{
Q_OBJECT
public slots:
void poll();
signals:
void finished();
void displayMessage(QString message);
}
// poll() method
void Poller::poll()
{
if(isCardDetected)
emit displayMessage("Detected"); // this will be sent to Dialog2 to display the message in the label
else
emit displayMessage("No card detected");
}
这是我打印 threadID 时的输出:
[Dialog2] from main thread: 0xb6fed000
[Dialog1] from main thread: 0xb6fed000
[Poller] from poller thread: 0xb0aff400
[DownloadClass] from downloader class: 0xb02ff400
请注意threadID
和是相同的Dialog1
。Dialog2
解决方案
推荐阅读
- spring-security - Vault 错误:更正应用程序的类路径,以便包含一个兼容的 org.springframework.vault.support.SslConfiguration 版本
- haskell - 从元组列表中获取函数
- c++ - 这个 C++ 中的主动对象模式示例有什么问题?
- r - 通过比较 R 中的其他两列来选择组
- graphql - 在 GraphQL 中对 Join 表进行批量更新的最佳方法是什么?
- reactjs - 如何加快组件和类的 npm 库的 webpack 重建
- r - 在 Windows [rstudio] [r] [windows] 中使用 R(或特别是 R Studio)在指定文件夹中打开文件资源管理器
- c - 为什么在 http 服务器中需要异步?
- dns - 无法连接到在 AWS lightail windows server 2019 上设置的域控制器
- makefile - 配置make在不同目录下为不同系统构建对象