How to delete a QTimer from another function?



  • Hi,
    so my problem is that i'm trying to make a QGraphicsRectItem move until it collides with another Item and then go back to its starting position, and I'm using a QTimer to iterate the movement function.
    I set it so that on the second collision it detects it should stop the QTimer and so on.
    It seems to work just fine until i try to make him do the same routine again, because the rect seems to be accelerating a bit more every time, to the point where it starts bouncing back from the starting wall, that is what i'm trying to avoid. From what i've gained i think the problem is that the timer never really stops, so from the second iteration on there seems to be some kind of conflict between the old and the new timer or something like that.
    is there some way i can put QTimer* timer= new QTimer () inside the (event->key()== Qt::Key_A) "function" and then stopping it and deleting it from inside the movePlayer() function?

    player.h

    #ifndef PLAYER_H
    #define PLAYER_H

    #include <QGraphicsRectItem>
    #include <QGraphicsScene>
    #include <QObject>
    #include <QTimer>
    #include <vector>

    using namespace std;
    class Player: public QObject , public QGraphicsRectItem
    {
    Q_OBJECT
    public:
    Player();
    void keyPressEvent(QKeyEvent *event);
    vector<int> *v= new vector<int>(0);
    QTimer *timer = new QTimer();

    public slots:

    void movePlayer();
    

    private:
    int speed=40;

    };

    #endif // PLAYER_H

    player.cpp

    #include "player.h"

    #include <QKeyEvent>
    #include <QTimer>
    #include <QList>
    #include <typeinfo>
    #include <vector>
    #include <QGraphicsScene>
    #include "enemy.h"

    using namespace std;

    Player::Player()
    {
    setRect(0,0,230,240);

    }

    void Player::keyPressEvent(QKeyEvent *event)
    {
    if(event->key()== Qt::Key_Left)
    {
    if(pos().x()>0)
    setPos(x()-10,y());
    }
    else if(event->key()== Qt::Key_Right)
    {
    if(pos().x()+230 < 1100)
    setPos(x()+10,y());
    }
    else if(event->key()== Qt::Key_A)
    {

        timer->start(100);
        connect(timer, SIGNAL(timeout()), this,SLOT(movePlayer()));
        
    
    }
    

    }

    void Player:: movePlayer()
    {

    if (scene()->collidingItems(this).isEmpty())
    {
      setPos(x()+speed,y());
    }
    else
    {
        v->push_back(1);
        if(v->size()>= 2)
        {
            v->clear();
            timer->stop();
            
    
        }
        int m=-speed;
        speed=m;
        setPos(x()+speed,y());
    
    }
    

    }


  • Qt Champions 2016

    @Tiziano-Boni
    hi and welcome
    It seems to be the same class?
    You can simply have the Timer as a member variable and call start/stop
    when needed. no reason create it on every key event.
    That way its available to all functions.

    Sorry, you seems to have done that already, the non formating makes it hard to really see.

    If you call stop on a timer it should stop for good.

    Also
    Calling this more than once
    connect(timer, SIGNAL(timeout()), this,SLOT(movePlayer()));
    will make it called many times.!
    You should only call this once. ( or use flag )



  • mrjj, first of all thank you so much for the quick reply,
    the problem was in fact the "redeclaration" of connect(timer, SIGNAL(timeout()), this,SLOT(movePlayer()));
    once i moved that line to the constructor everytime i press the "a" key seems to work perfectly!
    thanks a lot again!


  • Qt Champions 2016

    @Tiziano-Boni
    Super
    Happy game making :)

    Note to future readers:
    using
    connect(timer, SIGNAL(timeout()), this,SLOT(movePlayer()),Qt::UniqueConnection);
    might also have worked.


Log in to reply
 

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