如何在Qt中临时断开带有插槽的信号?
我用信号连接插槽。但现在我想暂时断开它们的连接 这是我的班级宣言的一部分:如何在Qt中临时断开带有插槽的信号?,qt,signals-slots,Qt,Signals Slots,我用信号连接插槽。但现在我想暂时断开它们的连接 这是我的班级宣言的一部分: class frmMain : public QWidget { ... private: QTimer *myReadTimer; ... private slots: void on_btnDownload_clicked(); ... }; 在frmMain的构造函数中,我将myReadTimer与插槽连接,以便每隔5秒调用ReadMyCom: myReadTimer=ne
class frmMain : public QWidget
{
...
private:
QTimer *myReadTimer;
...
private slots:
void on_btnDownload_clicked();
...
};
在frmMain
的构造函数中,我将myReadTimer
与插槽连接,以便每隔5秒调用ReadMyCom
:
myReadTimer=new QTimer(this);
myReadTimer->setInterval(5000);
connect(myReadTimer,SIGNAL(timeout()),this,SLOT(ReadMyCom()));
但是,在卸载时的插槽中单击了
。我不想myReadTimer
在单击的范围内发出任何信号。因此,我想在单击的
上的的开头断开它们的连接,并在最后重新连接它们。像这样:
void frmMain::on_btnDownload_clicked()
{
//some method to disconnect the slot & singal
...//the code that I want myReadTimer to leave me alone
//some method to reconnect the slot & singal
}
我在Stackoverflow中搜索,得到了一些答案,比如调用QObject
析构函数。但我不知道如何使用它
我还尝试使用断开连接
,例如:
QMetaObject::Connection myConnect;
myConnect=connect(myReadTimer,SIGNAL(timeout()),this,SLOT(ReadMyCom()));
...
disconnect(& myConnect);
但它仍然不起作用。有人能帮我怎么做吗?断开/重新连接语法
有许多方法可以调用disconnect,具体取决于您想要断开连接的内容。有关其工作原理的说明,请参阅
下面是一个使用0表示“断开所有插槽”的示例
或者,您可以通过复制“connect”语法来指定要断开的确切信号插槽对,如下所示:
disconnect(myReadTimer,SIGNAL(timeout()),this,SLOT(ReadMyCom()));
停止计时器
由于您使用的是计时器,这可能更简单:
void frmMain::on_btnDownload_clicked()
{
// stop the timer (so you won't get any timeout signals)
myReadTimer->stop();
...//the code that I want myReadTimer to leave me alone
// restart the timer (using whatever interval was set previously)
myReadTimer->start();
}
与原始方法的不同之处:
- 由于您正在停止并重新启动计时器,因此下次触发计时器的时间将是插槽功能完成后的
interval
- 如果单击卸载时的
需要一段时间才能执行,则在单击卸载时的
完成后,可能会有多个
事件排队。(请注意,此时您的操作基本上会“锁定”GUI一段时间;重构函数或为其提供自己的线程可能更有意义。)ReadMyCom
QObject
中有一个非常好的函数,它经常派上用场:QObject::blockSignals()
这是一个非常简单的fire-and-forget类,它可以满足您的需要。我不相信它的设计,我很久以前在网上的某个地方找到了它。不过要小心,它会阻止所有对象的所有信号。如果这不是您想要的,您可以修改该类以满足您的需要
class SignalBlocker{
public:
SignalBlocker(QObject *o): object(o), alreadyBlocked(object->signalsBlocked()){
if (!alreadyBlocked){
object->blockSignals(true);
}
}
~SignalBlocker() {
if (!alreadyBlocked){
object->blockSignals(false);
}
}
private:
QObject *object;
bool alreadyBlocked;
};
在您的情况下,使用变得微不足道
void frmMain::on_btnDownload_clicked()
{
SignalBlocker timerSignalBlocker(myReadTimer);
...//the code that I want myReadTimer to leave me alone
// signals automatically unblocked when the function exits
}
更新:
我从Qt5.3中看到,一个非常类似的类已经正式添加到API中。它的功能集稍大,与上面的功能集类似。我建议您改用官方类,以使您的代码库在任何API更改时保持最新
但是,用法仍然完全相同。您是否查看了
断开连接的文档?它采用与connect相同的参数。我阅读了disconnect的文档,发现了staticbooldesconnect(constqmetaobject::Connection&)代码>那么我是怎么错的呢?您使用QObject::disconnect()的示例是正确的,除了示例在预期引用的位置传递一个指针,所以它甚至不应该编译<代码>断开连接(myConnect)
工作。
void frmMain::on_btnDownload_clicked()
{
SignalBlocker timerSignalBlocker(myReadTimer);
...//the code that I want myReadTimer to leave me alone
// signals automatically unblocked when the function exits
}