大佬教程收集整理的这篇文章主要介绍了Qt 中的信号/槽向量?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
首先介绍一下我为什么要这样做的背景:我有一个类,比如说 @H_615_3@masterClass,它是 QWidget
的子类,它创建多个新的 QObject
派生类对象,比如 SlaveClass,这会在运行时动态发生。使用 QThread
将新的 SlaveClass 移动到新的 @H_863_7@movetoThread,因为它必须进行长时间运行的计算,而且我不希望我的 GUI 冻结。由于 SlaveClass 在不同的线程中,我调用 SlaveClass 中的任何方法的正确方法是使用 Qt 的信号/插槽机制和 Qt::QueuedConnection
。 SlaveClass 有许多信号和插槽,我想将它们连接到我的 MasterClass。我想要做的是在我的 MasterClass 中创建一个 signals 和 slots 的 QVector
,以便我可以动态地添加和删除它,{{1 }} 和 connect
这些到我的 SlaveClass 取决于 SlaveClass 是被创建还是销毁。
为了测试我的理论,我创建了一个 @H_330_19@masterClass 并尝试在其中创建 signals 和 slots 的向量并尝试连接 signals 到 slots 看看它是否有效:
第一次尝试[不起作用]:
大师班.h
disconnect
@H_709_2@masterclass.cpp
#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;
};
这给出了 2 个错误:
错误编号。上面 2 是因为我在 #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],&MasterClass::vSlt[1]);
connect(this,&MasterClass::vSig[2],&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";
}
下声明了 QVector<std::function<voID(int)>> vSig;
,在 signals:
下声明了 QVector<std::function<voID(int)>> vSlt;
。一旦我将上述两个向量移到 private slots:
下,这个错误就会消失。
第二次尝试 [有效,但只是一种]:
大师班.h
private:
@H_709_2@masterclass.cpp
.
.
.
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;
};
这有效并打印: 78 69 60
这里有两点需要注意:
.
.
.
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,&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";
}
行,它不会打印任何内容。connect(this,&MasterClass::slt_test);
和 vSig
向量时参数的变化。从输出中,我可以看到正确的 vSlt
被调用,因为它将第二个 vSig
函数的参数加 1,并将第三个 vSig
函数的参数加 2。但是,它不会将第二个 vSig
函数的参数加 10 或第三个 vSlt
函数的参数加 20,这让我怀疑它是否调用了正确的 vSlt
函数还是只是调用 vSlt
函数?有什么办法可以改进吗?
动态创建 slt_test()
对象时,我必须执行类似的操作才能连接到它的插槽 SlaveClass
。可能吗?
附言我知道我可以使用 connect(MasterClasspointer,&MasterClass::vSig[ID],SlaveClasspointer,&SlaveClass::slotName);
函数,但我想尽可能避免使用它。
你可以有一个槽向量(一个 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(); });
另一种选择是过滤掉从插槽上带有错误 ID 的呼叫:
int slavEID = /*something*/
connect(masterPtr,[myID = slavEID,slavePtr] (int id) { if (myID == id) slavePtr->slot(); });
以上是大佬教程为你收集整理的Qt 中的信号/槽向量?全部内容,希望文章能够帮你解决Qt 中的信号/槽向量?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。