是否可以断开 QObject 的所有连接而不删除它
Posted
技术标签:
【中文标题】是否可以断开 QObject 的所有连接而不删除它【英文标题】:Is it possible to disconnect all of a QObject's connections without deleting it 【发布时间】:2015-08-20 17:34:26 【问题描述】:我有一个 QObject A,它连接到另一个 QObject B。现在我希望 A 连接到 C,第三个 QObject 并与 B 完全断开连接。
简单易懂!问题是我有很多 A,每个都有自己的一组信号和插槽(B/C 更通用)。到目前为止,我一直在为每种不同的类类型手动创建连接和断开连接方法。这些方法基本上是彼此的副本,将connect
交换为disconnect
调用,与don't repeat yourself 相悖。
所以我的问题是:以下功能是否可行?
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、QObject 和Signals and Slots 文档,但都没有成功(尽管这通常不能保证......)。
【问题讨论】:
QObject::disconnect();
doc.qt.io/qt-5/qobject.html#disconnect-5
@drescherjm 该文档指出Disconnects all signals in this object from receiver's method.
我正在阅读它,因为它将所有 this 对象的信号与 other 对象的插槽断开连接,但我'我仍然不确定它是否也将 other 对象的信号与 this 对象的插槽断开。
这是我的解决方案,只需保留对以前发件人的引用,并在需要时致电disconnect
。
【参考方案1】:
至少有两种方法。首先,断开所有连接。
disconnect(obj,0,0,0);
//or
obj->disconnect();
第二。每个connect()
返回QMetaObject::Connection
可以复制或移动,因此您可以在列表中保存一些连接,一段时间后,只需遍历列表并为每个对象调用disconnect()
。一个连接的示例:
QMetaObject::Connection m_connection;
//…
m_connection = QObject::connect(…);
//…
QObject::disconnect(m_connection);
奖励:不,Qt 不支持如此深入的自省,您无法获取所有连接的插槽或其他内容的列表,但在大多数情况下您根本不需要它。 Qt 提供的一个有用函数是sender()
,它是指向发送信号的对象的指针。
编辑
正如docs所说:
断开连接到对象信号的所有东西
所以在下一个示例中,两个窗口都会显示:
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);
,但这当然是一个非常糟糕的方法。所以你可以使用我回答中的第二个建议:
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");
【讨论】:
不错的答案,disconnect everything
是否断开传入和传出连接?
因此,这会断开所有传出连接,但不会断开传入连接,这一点更重要。以上是关于是否可以断开 QObject 的所有连接而不删除它的主要内容,如果未能解决你的问题,请参考以下文章
由于从挂起的 *** 连接断开而不中断工作流而刷新网络驱动器的方法