是否可以断开所有QObject的连接而不删除它 [英] Is it possible to disconnect all of a QObject's connections without deleting it

查看:73
本文介绍了是否可以断开所有QObject的连接而不删除它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个QObject A,它连接到另一个QObjectB.现在我希望A连接到C,第三个QObject并与B完全断开连接.

I have a QObject A, this is connected to another QObject B. Now I want A to connect to C, a third QObject and to completely disconnect from B.

轻松自如!麻烦的是我有很多A,每个A都有自己的信号和插槽集(B/C比较通用).到目前为止,我一直在为每种不同的类类型手动进行连接和断开连接的方法.这些方法基本上是彼此的副本,将 connect 交换为 disconnect 调用,与

Easy peasy! Trouble is I have a lot of of A's each with their own set of signals and slots (B's/C's are more generic). So far I have been manually making a connect and a disconnect method for each different class type. The methods are basically copies of each other exchanging the connect for disconnect call, going against the don't repeat yourself).

所以我的问题是:以下功能可能吗?

So my question is: Is the following function possible?

void deleteAllConnections(QObject* someObject) {
    // TODO disconnect all connections owned by someObject
    // For bonus points: Is there a way of accessing the QMetaObject connected to?
}

我在 QMetaObject

I've poked around in the QMetaObject, QObject and the Signals and Slots documentation with no luck (though that is often not a guarantee...).

推荐答案

至少有2种方法.首先,断开所有连接.

There are at least 2 ways. First, disconnect everything.

disconnect(obj,0,0,0);
//or
obj->disconnect();

第二.每个 connect()返回 QMetaObject :: Connection ,它可以被复制或移动,因此您可以在列表中保存一些连接,一段时间后,只需遍历列表并为每个对象调用 disconnect()即可.一个连接的示例:

Second. Every connect() returns QMetaObject::Connection which can be copied or moved, so you can save some connections in the list and after some time, just iterate through the list and call disconnect() for every object. Example with one connection:

QMetaObject::Connection m_connection;
//…
m_connection = QObject::connect(…);
//…
QObject::disconnect(m_connection);

奖金:不,Qt不支持这种深层的内省,您无法获得所有已连接插槽或其他内容的列表,但是在大多数情况下,您根本不需要此功能.Qt为您提供的一个有用的函数是 sender(),它是指向发送信号的对象的指针.

Bonus: no, Qt doesn't support such deep introspection, you can't get list of all connected slots or something else, but in most cases you don't need this at all. One useful function that Qt gives you is sender(), which is a pointer to the object that sent the signal.

修改

文档表示:

断开与对象信号连接的所有内容

Disconnect everything connected to an object's signals

因此在下一个示例中,将显示两个窗口:

So in the next example both windows will be shown:

QWidget *a = new QWidget;
QWidget *b = new QWidget;

a->setWindowTitle("A");
b->setWindowTitle("B");

QObject::connect(a,SIGNAL(objectNameChanged(QString)), b, SLOT(show()));
QObject::connect(b,SIGNAL(objectNameChanged(QString)), a, SLOT(show()));

//a->disconnect();

a->setObjectName("A");
b->setObjectName("B");

但取消注释 a-> disconnect(); ,仅显示 A 窗口.这意味着 QObject :: connect(b,SIGNAL(objectNameChanged(QString)),a,SLOT(show())); 并未按照文档中的说明断开连接.如果您想解决这个难题,可以执行 a-> disconnect(b);b-> disconnect(a); ,但这当然是非常糟糕的方法.因此,您可以使用我的回答中的第二条建议:

But uncomment a->disconnect(); and only A windows will be shown. It means that QObject::connect(b,SIGNAL(objectNameChanged(QString)),a,SLOT(show())); was not disconnected as stated in the doc. If you want to solve this puzzle you can do a->disconnect(b); b->disconnect(a);, but it is of course a very bad approach. So you can use second suggestion from my answer:

QList<QMetaObject::Connection> connections;

QWidget *a = new QWidget;
QWidget *b = new QWidget;

a->setWindowTitle("A");
b->setWindowTitle("B");

connections << QObject::connect(a,SIGNAL(objectNameChanged(QString)), b, SLOT(show()));
connections << QObject::connect(b,SIGNAL(objectNameChanged(QString)), a, SLOT(show()));

foreach (auto var, connections) {
    QObject::disconnect(var);
}

a->setObjectName("A");
b->setObjectName("B");

这篇关于是否可以断开所有QObject的连接而不删除它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆