QtConcurrent::运行发出信号
QtConcurrent::run emit signal
我想在Qt中发出一个信号,从我用QtConcurrent调用的函数::run
这可能吗?我的位置好像从来没被叫过。所有的信号、槽和函数都是同一个类对象的一部分。我已经尝试在主线程和从线程中进行连接。我真的不关心信号和插槽是否在同一个线程中,我只是想让它发生。
谢谢
下面的代码在Qt 4.8.7中运行良好。信号从工作线程发出,并在主线程中消耗。我们断言槽在主线程中运行,函子在工作线程中运行。
// https://github.com/KubaO/stackoverflown/tree/master/questions/concurrent-emit-qt4-7114421
#include <QtCore>
class Helper : public QObject {
Q_OBJECT
public:
int n = 0;
Q_SLOT void increment() {
Q_ASSERT(QThread::currentThread() == qApp->thread());
n++;
}
};
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
Helper helper;
Q_ASSERT(helper.n == 0);
QtConcurrent::run([&]{
Q_ASSERT(QThread::currentThread() != qApp->thread());
QObject src;
QObject::connect(&src, SIGNAL(destroyed(QObject*)), &helper, SLOT(increment()));
QObject::connect(&src, SIGNAL(destroyed(QObject*)), &app, SLOT(quit()));
});
app.exec();
Q_ASSERT(helper.n == 1);
}
#include "main.moc"
在Qt 5中,您不需要helper类来演示它的工作:
#include <QtConcurrent>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
int n = 0;
Q_ASSERT(n == 0);
QtConcurrent::run([&]{
Q_ASSERT(QThread::currentThread() != qApp->thread());
QObject src;
QObject::connect(&src, &QObject::destroyed, &app, [&]{
Q_ASSERT(QThread::currentThread() == qApp->thread());
n ++;
qApp->quit();
});
});
app.exec();
Q_ASSERT(n == 1);
}
您可以为该连接使用Qt::QueuedConnection
(将其传递给建立连接的connect
调用),因为信号将始终从与接收器对象线程不同的线程发出。
Qt::AutoConnection
也会做同样的事情,并将信号添加到接收对象的线程的事件队列中。
如果接收线程被阻塞,因此永远不会重新进入事件队列,则信号无法被接收对象的插槽接收。
你真的应该使用QFuture和QFutureWatcher与QtConcurrent::run()。
是有可能的。看一个小例子:
在这个例子中,我们想要实现多线程。longProcess函数进入线程池并在线程池中进行处理,然后返回到主线程Test.h
Class Test: public QObject
{
Q_OBJECT
public:
explicit Test(QObject *parent = nullptr);
void resultAvailable();
static void doLongProcess(Test *test);
signals:
void finishedProcess(const QString &massage);
public slots:
void captureSignal(const QString &message);
};
Test.cpp
void Test::resultAvailable()
{
QtConcurrent::run(&ContactsModelManager::doLongProcess, this);
connect(this , &Test::finishedProcess,
this , &Test::captureSignal);
}
//attention!! doLongProcess is static fnuction
void Test::doLongProcess(Test *test)
{
//this process is very long
test->longProcess();
}
void Test::longProcess()
{
//do your process
//at the end emit your signal
emit finishedProcess("finished process in another thread");
}
void Test::captureSignal(const QString &message)
{
Qdebug() << "message is: " << message;
}
相关文章:
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- 运行时错误地址清理器:LEETCODE 中的致命信号
- 如何在长时间运行的方法中等待信号?
- 在绑定中捕获 fortran 运行时错误和信号C++
- 代码在我的系统中运行良好,但 coursera 自动评分器给了我未知的信号
- 在SIGABRT c ++信号之后继续运行程序
- 是信号处理程序,旨在无限期运行
- 运行时特性测试、setjmp、longjmp和信号掩码
- 在父母获得杀死信号和退出后,用system()产生的儿童进程继续运行
- 在通过ProcessBuilder运行的C程序中捕获信号
- 当将应用程序作为启动的守护程序运行时,C++ 库中的信号 10 (SIGBUS)
- 从Wt小部件信号事件运行popen()时出现问题
- sigaction SIGINT,程序在 & (background) 中运行,没有得到信号
- 在 QThread 中运行长时间操作并将信号发送到主线程仍会冻结 UI
- 运行时可用信号列表
- 如何克服运行时错误信号:25?等效地,浮点错误:核心转储
- 使用sigaltstack可以动态更改运行信号处理程序的堆栈
- 每次我在linux c++中为命名管道运行程序时,都会发出SIGSTOP信号
- 简单C++代码上的运行时错误信号11
- 如何在Qt中运行函数时断开所有信号