Help Please! Signals & Slots: When objects destroyed



  • Hi all, I want to set up three timer objects such that,

    • When two of them have completed their slots after some X iterations, they both get disconnected and destroyed.
    • Only when both are destroyed, the third timer activates.
    • I am having trouble with the destroyed(QObject*) signals for the first two timers.
    • They have to be interval type.
    • I am not able to get the object name of the destroyed object from the signal emitted by destroyed()
    • Why is it that slot B is displayed first, even though I called timerA->start() first?

    Here is what I have done so far.

    QDebug Output:
    slot B
    slot A
    Destroyed ""
    Destroyed ""

    int A,B,C;
    bool Adestroyed =false, Bdestroyed= false;
    
    void MainWindow::doThat()
    {
        timerA = new QTimer(this);
        timerB = new QTimer(this);
        timerC = new QTimer(this);
        timerA->setInterval(100);
        timerB->setInterval(100);
        timerC->setInterval(100);
        connect(timerA,SIGNAL(timeout()),this,SLOT(slotA()));
        connect(timerB,SIGNAL(timeout()),this,SLOT(slotB()));
        connect(timerC,SIGNAL(timeout()),this,SLOT(slotC()));
    
        connect(timerA,SIGNAL(destroyed(QObject*)),this,SLOT(sigIsDisconnected(QObject*)));
        connect(timerB,SIGNAL(destroyed(QObject*)),this,SLOT(sigIsDisconnected(QObject*)));
    
        timerA->start();
        timerB->start();
    
    }
    
    void MainWindow::slotA()
    {
        if(A<1){
            qDebug()<<"slot A";
            A++;
        }
        else{
            timerA->stop();
            disconnect(timerA,SIGNAL(timeout()),this,SLOT(slotA()));
            timerA->destroyed(this->timerA);
        }
    
    }
    
    void MainWindow::slotB()
    {
        if(B<1){
            qDebug()<<"slot B";
            B++;
        }
        else{
            timerB->stop();
            disconnect(timerB,SIGNAL(timeout()),this,SLOT(slotB()));
            timerB->destroyed(this->timerB);
        }
    }
    
    void MainWindow::slotC()
    {
        if(C<2){
            qDebug()<<"slot C";
            C++;
        }
        else{
            timerC->stop();
            disconnect(timerC,SIGNAL(timeout()),this,SLOT(slotC()));
        }
    }
    
    void MainWindow::sigIsDisconnected(QObject* obj)
    {
        qDebug()<<"Destroyed "<<obj->objectName();
    
            if(obj->objectName()=="timerA"){
                Adestroyed=true;
            }
            if(obj->objectName()=="timerB"){
                Bdestroyed=true;
            }
    
            if(Adestroyed&&Bdestroyed){
                timerC->start();
            }
    }
    

  • Lifetime Qt Champion

    Hi,

    You don't set any object name on your timer objects so there's no reasons for the function to return anything.

    Calling a signal from an object like that is wrong. The signals are called from within the class implementation.

    The destroyed signal will get called once an object is deleted which you don't do for timerA nor timerB.

    Based on your slots implementation, why do the timers have to be interval since they will only run once anyway ?

    Also, why use static variables outside of your MainWindow class to handle that case ?



  • void MainWindow::doThat()
    {
    // private: int m_numDestroyed;
    m_numDestroyed = 0;
    for(QTimer*& singleTim : {timerA ,timerB ,timerC }){
        singleTim = new QTimer(this);
        singleTim ->setInterval(100);
    singleTim->setSingleShot(true);
    }
    const auto checkDestroyed=[=]()->void{
    if(++m_numDestroyed>1){
    delete numDestroyed;
    timerC->start();
    };
        connect(timerA,&QTimer::timeout,this,[=]()->void{
    qDebug("slot A");
    checkDestroyed();
    }
    });
        connect(timerB,&QTimer::timeout,this,[=]()->void{
    qDebug("slot B");
    checkDestroyed();
    }
    });
        connect(timerC,&QTimer::timeout,this,[=]()->void{
    qDebug("slot C");
    }
    });
    connect(timerA,&QTimer::timeout,timerA,&QTimer::deleteLater);
    connect(timerB,&QTimer::timeout,timerB,&QTimer::deleteLater);
    
        timerA->start();
        timerB->start();
    
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.