当Qt-Slot位于通过std::async创建的线程上时,它不会被调用
Qt Slot is not called when it lives on a thread created via std::async
我想创建一个Qt小部件,它通过signal/slot系统与不同线程上的其他类通信。接收对象是在一个函数中创建的,该函数通过std::async运行。问题是:如果小部件发出信号,则不会调用另一个线程上的插槽。
我的例子:
我创建了Class MainWindow,它派生自QMainWindow,并将在主线程上运行。Reciver类是在一个通过std::async调用的函数中创建的,它有一个线程,应该向控制台打印一些内容。
我测试了信号是否是通过将其连接到同一线程上的另一个插槽来发出的,这很好。
主窗口.hpp
#pragma once
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
signals:
void send();
private slots:
void buttonClicked();
void recieve();
};
主窗口.cpp
#include "MainWindow.hpp"
#include <iostream>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
QPushButton* start = new QPushButton("Start");
setCentralWidget(start);
start->show();
connect(start, SIGNAL(clicked(bool)), this, SLOT(buttonClicked()));
connect(this, SIGNAL(send()), this, SLOT(recieve()));
}
void MainWindow::buttonClicked()
{
std::cout << "MainWindow::buttonClicked()n";
emit send();
}
void MainWindow::recieve()
{
std::cout << "MainWindow::recieve()n";
}
Reciver.hpp
#include <QObject>
class Reciever : public QObject
{
Q_OBJECT
public:
Reciever(QObject *parent = 0);
public slots:
void recieve();
};
接收器.cpp
#include "Reciever.hpp"
#include <iostream>
Reciever::Reciever(QObject *parent) : QObject(parent)
{
std::cout << "Reciever()" << std::endl;
}
void Reciever::recieve()
{
std::cout << "Reciever::recieve()" << std::endl;
}
main.cpp
#include "MainWindow.hpp"
#include "Reciever.hpp"
#include <QApplication>
#include <future>
void StartAndConnect(MainWindow &widget)
{
Reciever* rec = new Reciever();
QObject::connect(&widget, SIGNAL(send()), rec, SLOT(recieve()));
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow myWidget;
myWidget.show();
auto future = std::async(std::launch::async, [&myWidget](){
StartAndConnect(myWidget);
});
app.exec();
future.wait();
}
经过一些研究,我最强烈的猜测是,std::async启动的线程没有Qt事件循环,因此不会达到处理发布事件(emit)的地步。我将main改为使用QtConcurrent::run,但它也不起作用。
编辑
这是我对QtConcurrent:的尝试
main2.cpp
#include "MainWindow.hpp"
#include "Reciever.hpp"
#include <QApplication>
#include <future>
#include <QtConcurrent>
void StartAndConnect(MainWindow &widget)
{
Reciever* rec = new Reciever();
QObject::connect(&widget, SIGNAL(send()), rec, SLOT(recieve()));
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow myWidget;
myWidget.show();
auto future = QtConcurrent::run( [&myWidget](){
StartAndConnect(myWidget);
});
app.exec();
future.waitForFinished();
}
如果要处理跨线程槽调用,则需要在线程中运行事件循环。
auto future = QtConcurrent::run( [&myWidget](){
StartAndConnect(myWidget);
QEventLoop e;
e.exec();
});
但我建议使用QThread
,因为在您的情况下,这是显而易见的。Qt有一个非常好的文档,描述了您的案例。
相关文章:
- 变量没有改变?通过向量的函数调用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 使用QTreeView,如何通过调用函数只突出显示特定的行/列
- 通过引用传递-为什么要调用这个析构函数
- C ++:通过大括号调用构造函数?
- 如何通过命名空间调用非静态方法
- 从C++调用 Python 并访问通过 Anaconda 安装的软件包
- 为什么我的运算符 + 重载尽管是通过引用传递的,但仍调用我的复制构造函数?
- 如何在 c# 代码中通过引用调用时从 c++ dll 更新数组值?
- 如何通过python方法和kwargs来提升python的c++函数和调用
- C++ 通过引用调用函数
- 通过直接函数调用将 std::p romise 对象传递给函数
- 通过 Qt 中的线程调用 Rust 库
- 检查程序是手动调用还是通过系统启动调用
- 它不是编译.我正在调用一个通过引用调用的函数,但有一个错误,无法将双*转换为双倍
- 如何通过调用函数(通过引用调用)来更改 std::set 元素?在 C++ 中
- 如何通过调用c#方法通过COM接口传递函数指针
- delete[]操作符是否适用于通过指针返回的动态分配的内存?
- 从非托管c++调用c#函数(通过托管包装器)
- 从c++中调用未知(通过名称)lua函数