使用 Qt GUI 打包线程程序
Packaging a threaded program with Qt GUI
我有一个工作完成的应用程序,它使用多个加速线程并且可以在命令行界面上正常工作。
我用"包装器"类打包了这个程序,以便我可以从Qt主窗口运行程序中的函数。
例如:
netWrap.getImgs(ui->sampleNameEdit->text().toStdString());
这将从带有文本框参数 sampleName 的网络程序中获取图像,并从由按钮触发的插槽调用。
这一切都工作正常,但是,某些函数(例如上面的函数)可能需要大约 20 秒才能运行,这会挂起 GUI。我希望它不要挂起 GUI。
显而易见的选择是使用 QThread
,但我不想向我的程序添加额外的类,因为这只应该是一个简单的前端。有没有办法我可以在线程中运行此功能并等待终止信号而不挂起 GUI?
编辑: 问题:
QFuture<int> run = QtConcurrent::run(&(netWrap.getImgs), ui->sampleNameEdit->text().toStdString());
这会产生 4 个错误,最相关的可能是:
error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&networkWrapper::getImgs' [-fpermissive]
QFuture<int> run = QtConcurrent::run(&(netWrap.getImgs), ui->sampleNameEdit->text().toStdString());
和:
error: no matching function for call to 'run(int (networkWrapper::*)(std::string), std::string)'
QFuture<int> run = QtConcurrent::run(&(netWrap.getImgs), ui->sampleNameEdit->text().toStdString());
你不会子类 QThread 在不同的线程中运行某些东西。QThread通过信号/插槽使用。
http://doc.qt.io/qt-5/qthread.html#started
默认的 QThread::run() 启动一个事件循环,允许您处理其他线程中的网络事件等内容。这意味着您连接到QThread::started信号,启动您的请求,然后它们在不同的线程中得到处理。然后,您可以使用另一个信号来指示您的主 GUI 线程,表明您已完成并且数据可用。
如果你只需要在不同的线程中调用某个函数,那么使用Qt Concurrent。这比QThread更容易使用。
http://doc.qt.io/qt-5/qtconcurrent.html#run
void my_function(int a, double b) {
.... do something in another thread ....
}
....
auto some_function = std::function<void(int, double)>(&my_function);
QFuture<void> ret = QtConcurrent::run(some_function, 10, 20.0);
....
或者不使用任何std::function,直接使用普通函数指针,
QFuture<void> ret = QtConcurrent::run(&my_function, 10, 20.0);
调用类成员,也一样简单,
class Foo {
public:
void foo(int a) {}
};
...
Foo *foo_instance = new Foo;
QFuture<void> ret = Qtconcurrent::run(foo_instance, &Foo::foo, 10);
...
并且您的函数正在另一个线程中运行。就是这么简单。
注意:不要从非 GUI 线程访问/操作 GUI 类。
你应该提供指向对象的指针,以及类成员函数的地址和所需的参数,如:
QFuture<void> future = QtConcurrent::run(netWrap, &networkWrapper::dbsChanged, ui->sampleNameEdit->text().toStdString());
您可以检查未来表示的异步计算的状态,例如:
if(future.isRunning())
{
// It is currently running
}
或者等待它完成:
future.waitForFinished();
QtConcurrent::run()
不会像QtConcurrent::mappedReduced()
那样自动提供进度信息。但是您可以使用信号拥有自己的进度报告机制。
要通知终止,从函数发出信号以显示它已完成是一种简单的方法。
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- C++多线程程序:变量定义为类成员的隔离错误
- 在以读取为主的多线程程序中,可以使用原子来减少锁定吗
- 多线程程序中的分段故障和gdb回溯上的不完整信息
- 多线程程序卡在优化模式下,但在 -O0 中正常运行
- 在使用 std::cout 和多线程程序中如何避免数据竞争<iomanip>?
- 控制多线程程序中的输出流
- 使用 vector<thread> 和 .join() 未并行运行的多线程C++程序
- gdb:在多线程程序中调用函数,不进行线程
- 关于多线程程序中的临时对象
- 简单线程程序的链接器错误(缺少boost_chrono符号)
- C 中的多线程程序:在标志变量上使用Mutex
- c++:写入多线程程序中的文件
- 使用优化编译时的多线程程序块
- 如何读取锁定多线程C++程序
- 使用OpenSSL和锁随机崩溃的多线程程序
- 多线程程序中的K最近的邻居
- MFC多线程程序可以以并行方法运行