I connect a slot with a signal. But now I want to disconnect them temporarily.
Here is part of my class declaration:
class frmMain : public QWidget
{
...
private:
QTimer *myReadTimer;
...
private slots:
void on_btnDownload_clicked();
...
};
In the constructor of frmMain
, I connect myReadTimer
with a slot so that ReadMyCom
will be called every 5 seconds:
myReadTimer=new QTimer(this);
myReadTimer->setInterval(5000);
connect(myReadTimer,SIGNAL(timeout()),this,SLOT(ReadMyCom()));
But, in slot on_btnDownload_clicked
. I don't want myReadTimer
to emit any signal in on_btnDownload_clicked
's scope. So I want to disconnect them at the beginning of on_btnDownload_clicked
and reconnect them in the end. Like this:
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
}
I searched in Stackoverflow and got some answer like call the QObject
destructor. But I don't know how to use it.
I also tried to use disconnect
, like:
QMetaObject::Connection myConnect;
myConnect=connect(myReadTimer,SIGNAL(timeout()),this,SLOT(ReadMyCom()));
...
disconnect(& myConnect);
But it still not work. So could any one help me how to do this?
There is a very nice function in QObject
that comes in handy every now and again: QObject::blockSignals()
Here's a very simple fire-and-forget class that will do what you want. I take no credit for it's design, I found it on the internet somewhere a long time ago. Be careful though, it will block all signals to all objects. If this is not what you want, you can modify the class to suit your needs.
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;
};
Usage, in your case, becomes trivial
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
}
UPDATE:
I see that from Qt 5.3, a very similar class has been offically added to the API. It does a similar job as the one above with a slightly bigger feature-set. I suggest you use the official QSignalBlocker class instead in order to keep your codebase up-to-date with any API changes.
Usage, however, remains exactly the same.