C++ Qt中的信号/插槽向量?
首先是关于我为什么要这样做的背景:我有一个类,比如说MasterClass,它是C++ Qt中的信号/插槽向量?,c++,multithreading,qt,signals-slots,C++,Multithreading,Qt,Signals Slots,首先是关于我为什么要这样做的背景:我有一个类,比如说MasterClass,它是QWidget的一个子类,它创建了多个新的QObject派生类对象,比如SlaveClass,这在运行时动态发生。通过使用moveToThread将新的SlaveClass移动到新的QThread,因为它必须执行长时间运行的计算,并且我不希望我的GUI冻结。由于SlaveClass位于不同的线程中,因此我调用SlaveClass中任何方法的正确方法是使用Qt的Signal/Slot机制以及Qt::QueuedConn
QWidget
的一个子类,它创建了多个新的QObject
派生类对象,比如SlaveClass,这在运行时动态发生。通过使用moveToThread
将新的SlaveClass移动到新的QThread
,因为它必须执行长时间运行的计算,并且我不希望我的GUI冻结。由于SlaveClass位于不同的线程中,因此我调用SlaveClass中任何方法的正确方法是使用Qt的Signal/Slot机制以及Qt::QueuedConnection
。SlaveClass有很多信号和插槽,我想连接到我的MasterClass。我想做的是在我的MasterClass中创建一个包含信号和插槽的QVector
,这样我就可以动态地添加和删除它们,并且connect
和disconnect
连接到我的SlaveClass,具体取决于SlaveClass是被创建还是被销毁
为了验证我的理论,我创建了一个MasterClass,并尝试在其中创建信号向量和插槽,并尝试将信号连接到插槽,看看它是否有效:
第一次尝试[无效]:
大师班
#include <QWidget>
#include <QVector>
#include <QDebug>
#include <functional>
Class MasterClass : public QWidget
{
Q_OBJECT
public:
MasterClass(QWidget *parent = nullptr);
~MasterClass();
signals:
void sig_test(int testID);
QVector<std::function<void(int)>> vSig;
private slots:
void slt_test(int testID);
QVector<std::function<void(int)>> vSlt;
};
.
.
.
signals:
void sig_test(int testID);
private slots:
void slt_test(int testID);
private:
QVector<std::function<void(int)>> vSig;
QVector<std::function<void(int)>> vSlt;
};
masterclass.cpp
#include "masterclass.h"
MasterClass::MasterClass(QWidget *parent)
: QWidget(parent)
{
vSig << [this](int id) -> void{return this->sig_test(id); };
vSig << [this](int id) -> void{return this->sig_test(id); };
vSig << [this](int id) -> void{return this->sig_test(id); };
vSlt << [this](int id) -> void{return this->slt_test(id); };
vSlt << [this](int id) -> void{return this->slt_test(id); };
vSlt << [this](int id) -> void{return this->slt_test(id); };
connect(this, &MasterClass::vSig[0], this, &MasterClass::vSlt[0]);
connect(this, &MasterClass::vSig[1], this, &MasterClass::vSlt[1]);
connect(this, &MasterClass::vSig[2], this, &MasterClass::vSlt[2]);
emit vSig[0](78);
emit vSig[1](68);
emit vSig[2](58);
}
void MasterClass::slt_test(int testID)
{
qDebug() << "\n" << testID << "\n";
}
.
.
.
vSig << [this](int id) -> void{return this->sig_test(id); };
vSig << [this](int id) -> void{return this->sig_test(id + 1); }; // Notice change in argument
vSig << [this](int id) -> void{return this->sig_test(id + 2); }; // Notice change in argument
vSlt << [this](int id) -> void{return this->slt_test(id); };
vSlt << [this](int id) -> void{return this->slt_test(id + 10); }; // Notice change in argument
vSlt << [this](int id) -> void{return this->slt_test(id + 20); }; // Notice change in argument
connect(this, &MasterClass::sig_test, this, &MasterClass::slt_test);
emit vSig[0](78);
emit vSig[1](68);
emit vSig[2](58);
}
void MasterClass::slt_test(int testID)
{
qDebug() << "\n" << testID << "\n";
}
。
.
.
vSig void{返回此->sig_测试(id);};
vSig void{返回此->sig_测试(id+1);};//注意论点的变化
vSig void{返回此->sig_测试(id+2);};//注意论点的变化
vSlt void{返回此->slt_测试(id);};
vSlt void{返回此->slt_测试(id+10);};//注意论点的变化
vSlt void{返回此->slt_测试(id+20);};//注意论点的变化
连接(此,&MasterClass::sig_测试,此,&MasterClass::slt_测试);
发射vSig[0](78);
发射vSig[1](68);
发射vSig[2](58);
}
void MasterClass::slt_测试(int testID)
{
qDebug()您可以有一个插槽向量(lambda函数可以是插槽),但您不能真正有一个信号向量。但是,您可以将您的信号连接到根据ID分派到正确插槽的对象:
// MasterClass.h
class MasterClass : public QObject {
// ... class stuff ...
signals:
void masterSignal(int id);
private:
std::unordered_map<int, SlaveClass*> m_slaveMap;
}
// MasterClass.cpp ...
connect(this, &MasterClass::masterSignal, slavePtr,
[](int id) { m_slaveMap[id]->slot(); });
我想它显然没有调用你的vSlt
插槽。为什么会这样?你从来没有将任何东西连接到这些插槽。谢谢,我理解,我也这么认为,但是为什么它要将vSig
信号连接到slt\u测试
插槽?我也从来没有这样连接过。只有sig\u test
连接到slt\u测试
vSig
只是一个函数向量。这些函数只需调用sig_test
。由于sig_test
连接到slt_test
,调用vSig
就可以到达slt_test
@JarMan谢谢,这很有意义:)谢谢!过滤不是一个好主意,因为它会创建数据的副本由于插槽位于不同的线程中,所以将g发送到插槽。我将尝试使用slavemap的第一种方法。
int slaveID = /*something*/
connect(masterPtr, &MasterClass::masterSignal, slavePtr,
[myID = slaveID, slavePtr] (int id) { if (myID == id) slavePtr->slot(); });