UI 在 QT c++ 中程序为 运行 时阻塞
UI blocks while the program is running in QT c++
我在 ui 中有一个 QT 应用程序。而且我的计算量很大。当计算开始时,我的程序在计算 运行 时停止响应。我想通过多线程来做到这一点,但我不能正确地实现它。我尝试使用默认的 lib 线程来做到这一点:
void HeavyCalculations()
{
// some heavy calculations
}
void MainWindow::on_pushButton_3_clicked()
{
// context is some object in whose context the finished signal should be called, so most likely your MainWindow
auto futureWatcher = new QFutureWatcher<void>(this);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, this, compulationFinished);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, futureWatcher, &QFutureWatcher<void>::deleteLater);
auto future = QtConcurrent::run( PackBytes );
futureWatcher->setFuture(future);
}
可是,th.join()
写到哪里呢?如果我把它放在下一行,它就没有意义了。那么,您有什么建议吗?
更新
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_3_clicked();
void compulationFinished();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
请参阅 Qt 中的 Multithreading Technologies 文章 - “最简单”的解决方案可能是使用 QtConcurrent
进行 运行 计算,并使用 QFutureWatcher
获得通知计算完成。
所以。类似的东西:
void MainWindow::on_pushButton_3_clicked()
{
// context is some object in whose context the finished signal should be called, so most likely your MainWindow
auto futureWatcher = new QFutureWatcher<void>(this);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, this, &MainWindow::computationFinished);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, futureWatcher, &QFutureWatcher<void>::deleteLater);
auto future = QtConcurrent::run( HeavyCalculations );
futureWatcher->setFuture(future);
}
void MainWindow::computationFinished()
{
// tell the user computation is finished or something
}
通过上述实现,您不需要自己的 QThread
对象,因此也不需要对其调用 join
。不过,当线程完成时您会收到通知(在上面的示例中调用了函数 computationFinished
),因此您可以向用户显示计算结果。
旁注:当然,您需要将 void computationFinished();
添加到 class 声明中(除非您在其他地方需要它,在 private slots:
部分)。
我在 ui 中有一个 QT 应用程序。而且我的计算量很大。当计算开始时,我的程序在计算 运行 时停止响应。我想通过多线程来做到这一点,但我不能正确地实现它。我尝试使用默认的 lib 线程来做到这一点:
void HeavyCalculations()
{
// some heavy calculations
}
void MainWindow::on_pushButton_3_clicked()
{
// context is some object in whose context the finished signal should be called, so most likely your MainWindow
auto futureWatcher = new QFutureWatcher<void>(this);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, this, compulationFinished);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, futureWatcher, &QFutureWatcher<void>::deleteLater);
auto future = QtConcurrent::run( PackBytes );
futureWatcher->setFuture(future);
}
可是,th.join()
写到哪里呢?如果我把它放在下一行,它就没有意义了。那么,您有什么建议吗?
更新
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_3_clicked();
void compulationFinished();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
请参阅 Qt 中的 Multithreading Technologies 文章 - “最简单”的解决方案可能是使用 QtConcurrent
进行 运行 计算,并使用 QFutureWatcher
获得通知计算完成。
所以。类似的东西:
void MainWindow::on_pushButton_3_clicked()
{
// context is some object in whose context the finished signal should be called, so most likely your MainWindow
auto futureWatcher = new QFutureWatcher<void>(this);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, this, &MainWindow::computationFinished);
QObject::connect(futureWatcher, &QFutureWatcher<void>::finished, futureWatcher, &QFutureWatcher<void>::deleteLater);
auto future = QtConcurrent::run( HeavyCalculations );
futureWatcher->setFuture(future);
}
void MainWindow::computationFinished()
{
// tell the user computation is finished or something
}
通过上述实现,您不需要自己的 QThread
对象,因此也不需要对其调用 join
。不过,当线程完成时您会收到通知(在上面的示例中调用了函数 computationFinished
),因此您可以向用户显示计算结果。
旁注:当然,您需要将 void computationFinished();
添加到 class 声明中(除非您在其他地方需要它,在 private slots:
部分)。