简体   繁体   中英

QTimer doesn't work outside main function

In short: this piece of code is located in main function and this works just well. This code performs swap on two graphic elements. 在此处输入图片说明

        QTimer timer;
        timer.setTimerType(Qt::PreciseTimer);
        timer.setInterval(1000.0/30.0);
        timer.setSingleShot(false);

    // ====================== MOVE 4 in POS of 1 ==========================
        QPointF centre(QLineF(button1->pos(), button4->pos()).pointAt(0.5));
        QPointF positionBut4 = button4->pos();

        MyPointF centreSwap4(0, &positionBut4, &centre);
        button4->myPointF = &centreSwap4;

        QObject::connect(&timer, SIGNAL(timeout()), &centreSwap4, SLOT(updateDownRight()));
        QObject::connect(&centreSwap4, SIGNAL(positionChanged()), button4, SLOT(slotMoveCircle()));

    // ====================== MOVE 4 in POS of 1 ==========================

    // ====================== MOVE 1 in POS of 4 ==========================
        QPointF positionBut1 = button1->pos();

        MyPointF centreSwap1(0, &positionBut1, &centre);
        button1->myPointF = &centreSwap1;

        QObject::connect(&timer, SIGNAL(timeout()), &centreSwap1, SLOT(updateUpLeft()));
        QObject::connect(&centreSwap1, SIGNAL(positionChanged()), button1, SLOT(slotMoveCircle()));
    // ====================== MOVE 1 in POS of 4 ==========================
        timer.start();

        QTimer::singleShot(3000, Qt::PreciseTimer, &timer, SLOT(stop()));

But when I want to put this piece of code out of main into a function (in order to shorten the code and perform swap on elements by just giving pointers to them) QTimer refuses to work(says it's active but timeout is not triggered):

    void animateSwap(QGraphicsRectWidget *w1, QGraphicsRectWidget *w2, QTimer &timer)
    {
        QGraphicsRectWidget *button4, *button1;
        if (w1->x() > w2->x())
        {
                button4 = w2;
                button1 = w1;
        }
        else
        {
            button4 = w1;
            button1 = w2;
        }
        // ====================== MOVE w2  in POS of w1 ==========================
        QPointF centre(QLineF(button1->pos(), button4->pos()).pointAt(0.5));
        QPointF positionBut4 = button4->pos();

        MyPointF centreSwap4(0, &positionBut4, &centre);
        button4->myPointF = &centreSwap4;

        QObject::connect(&timer, SIGNAL(timeout()), &centreSwap4, SLOT(updateDownRight()));
        QObject::connect(&centreSwap4, SIGNAL(positionChanged()), button4, SLOT(slotMoveCircle()));

        // ====================== !MOVE w2 in POS of w1 ==========================

        // ====================== MOVE w1 in POS of w2 ==========================
        QPointF positionBut1 = button1->pos();

        MyPointF centreSwap1(0, &positionBut1, &centre);
        button1->myPointF = &centreSwap1;

        QObject::connect(&timer, SIGNAL(timeout()), &centreSwap1, SLOT(updateUpLeft()));
        QObject::connect(&centreSwap1, SIGNAL(positionChanged()), button1, SLOT(slotMoveCircle()));
        // ====================== MOVE w1 in POS of w2 ==========================
        timer.start();

        qDebug() << timer.isActive();

        QTimer::singleShot(3000, Qt::PreciseTimer, &timer, SLOT(stop()));
    }

UPDATE: Now it works:

    void animateSwap(QGraphicsRectWidget *w1, QGraphicsRectWidget *w2, QTimer &timer, int cycles = 1)
    {
        QGraphicsRectWidget *button4, *button1;
        if (w1->x() > w2->x())
        {
                button4 = w2;
                button1 = w1;
        }
        else
        {
            button4 = w1;
            button1 = w2;
        }
        // ====================== MOVE w2  in POS of w1 ==========================
        QPointF centre(QLineF(button1->pos(), button4->pos()).pointAt(0.5));
        QPointF positionBut4 = button4->pos();

        MyPointF *centreSwap4 = new MyPointF(0, &positionBut4, &centre);
        button4->myPointF = centreSwap4;

        QObject::connect(&timer, SIGNAL(timeout()), centreSwap4, SLOT(updateDownRight()));
        QObject::connect(centreSwap4, SIGNAL(positionChanged()), button4, SLOT(slotMoveCircle()));

        // ====================== !MOVE w2 in POS of w1 ==========================

        // ====================== MOVE w1 in POS of w2 ==========================
        QPointF positionBut1 = button1->pos();

        MyPointF *centreSwap1 = new MyPointF(0, &positionBut1, &centre);
        button1->myPointF = centreSwap1;

        QObject::connect(&timer, SIGNAL(timeout()), centreSwap1, SLOT(updateUpLeft()));
        QObject::connect(centreSwap1, SIGNAL(positionChanged()), button1, SLOT(slotMoveCircle()));
        // ====================== MOVE w1 in POS of w2 ==========================
        timer.start();

        qDebug() << timer.isActive();

        QTimer::singleShot(3000 * cycles, Qt::PreciseTimer, &timer, SLOT(stop()));
    }

You are connecting the timeout() signal of the timer to eg

MyPointF centreSwap1(0, &positionBut1, &centre);

which is an object on the stack, and therefore local to the function and is deleted the moment the function finishes. Qt disconnects a connection if one of the objects (sender, receiver) is deleted, so the moment the timer finishes there is nothing connected to its timeout() signal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM