我有一个工作,完成的应用程序,它使用多个boost线程,并且可以通过命令行界面正常工作。
我用#34;包装"打包了这个程序。 class,以便我可以从Qt主窗口运行程序中的函数。
例如:
netWrap.getImgs(ui->sampleNameEdit->text().toStdString());
这会从文本框中使用参数sampleName从网络程序中获取图像,并从按钮触发的插槽中调用。
这一切都运行正常,但是,某些功能(例如上面的功能)可能需要大约20秒才能运行,这会挂起GUI。我希望不要挂起GUI。
显而易见的选择是使用QThread
,但我不想在程序中添加额外的类,因为这只是一个简单的前端。有没有办法可以在线程中运行此函数并等待终止信号而不挂起GUI?
编辑:QFutures:
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());
答案 0 :(得分:3)
你没有将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类。
答案 1 :(得分:1)
您应该提供指向对象的指针,以及类成员函数的地址和所需的参数,如:
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()
那样自动提供进度信息。但是您可以使用信号拥有自己的进度报告机制。
要通知终止,从功能中发出信号表明它已经完成是一种简单的方法。