Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

KeyPress / KeyRelease issue



  • Hi all!

    So my problem is quite simple, only the solution I don't see it,I want that when the "Z" key is pressed the robot moves forward. As long as you have not released the "Z" key, the camera should always move forward. Once you release the "Z" key the robot stops.
    I tried the function isAutoRepeat but it's always the same problem
    Here is the code portion:
    void Rover::keyPressEvent(QKeyEvent*keyevent)
    {

    switch(keyevent->key())
    {
    case Qt:: Key_Z:
    {
    Current_speed = ui->PWM_Curseur->value();
    gpioPWM (12, 1600 + Current_speed);
    gpioPWM (13, 1600 + Current_speed);
    qDebug() << 1600 + Current_speed ;
    qDebug() << "Forward";
    break;

       }
    

    }
    void Rover::keyReleaseEvent(QKeyEvent*keyevent)
    {

     if (keyevent->isAutoRepeat() == true)
    

    {
    keyevent->ignore();
    }

     else {
       gpioPWM (12, 0);
       gpioPWM (13, 0);
       qDebug()<<"keyReleased";
    }
     }
    

    }

    The debug console shows me:
    Forward
    Forward
    Forward
    keyReleased
    Forward
    Forward
    Forward
    keyReleased
    Forward
    Forward
    keyReleased

    What I would like it to display is as long as you press "Z" you get:
    Forward
    Forward
    Forward
    Forward
    Forward
    Forward

    Then once we release "Z" we get:
    keyReleased


  • Moderators

    @jack1998
    I would suggest the following.

    Give your Rover class a QTimer object, set it to a reasonable frequency

    m_timer.setInterval(20) // 50Hz
    

    create a zmove function and connect your timer to it

    Rover::moveZ(){
    qDebug() << "Forward";
    }
    
    ....
    connect(&m_timer, &QTimer::timeout, this, &Rover::moveZ);
    

    start the timer on z press and stop it on z release:

    void Rover::keyPressEvent(QKeyEvent*keyevent)
    {
    
    switch(keyevent->key())
    {
    case Qt:: Key_Z:
    {
    m_timer.start();
    moveZ() // initial move, the timer will only trigger after the interval
    break;
    
       }
    }
    
    void Rover::keyReleaseEvent(QKeyEvent*keyevent)
    {
    switch(keyevent->key())
    {
    case Qt:: Key_Z:
       m_timer.stop();
       break;
    }
    }
    


  • @J-Hilk thank you for your answer but it's still the same problem
    here is the code

    Rover .h :
    public :
    QTimer *m_timer;
    public slots :
    void move() ;

    Rover.cpp:
    m_timer = new Qtimer(this);
    m_timer->setInterval(20);
    connect(m_timer, SIGNAL(timeout()), this,SLOT(move()));
    void Rover::move(){
    Current_speed = ui->PWM_Curseur->value();
    gpioPWM (12, 1600 + Current_speed);
    gpioPWM (13, 1600 + Current_speed);
    qDebug() << 1600 + Current_speed ;
    qDebug() << "Forward";
    }
    void Rover::keyPressEvent(QKeyEvent*keyevent)
    {

    switch(keyevent->key())
    {
    case Qt:: Key_Z:
    {
    m_timer.start();
    move() // initial move, the timer will only trigger after the interval
    break;
    }
    void Rover::keyReleaseEvent(QKeyEvent*keyevent)
    {
    switch(keyevent->key())
    {
    case Qt:: Key_Z:
    m_timer.stop();
    gpioPWM (12, 0);
    gpioPWM (13, 0);
    qDebug()<<"keyReleased";
    break;
    }
    }


  • Moderators

    @jack1998 said in KeyPress / KeyRelease issue:

    m_timer.start();

    add a isRunning check, this may restart regularly and not time out

    if(!m_timer. isActive())
        m_timer.start();
    

  • Moderators

    
    #include <QApplication>
    #include <QDebug>
    #include <QKeyEvent>
    #include <QTimer>
    #include <QTime>
    
    class mWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit mWidget(QWidget * parent = nullptr) : QWidget(parent){
            QObject::connect(&m_Timer, &QTimer::timeout, this, &mWidget::moveSlot);
            m_Timer.setInterval(20);
        }
    
    protected:
        QTimer m_Timer;
    
        virtual void keyPressEvent(QKeyEvent *event) override{
            switch(event->key())
            {
            case Qt:: Key_Z:
            {
                if(!m_Timer.isActive()){
                    m_Timer.start();
                    moveSlot();
                }else
                    qDebug() << "Key Z when timer running";
            }
            default: qDebug() << "Other Key" << event->key();
            }
        }
    
        virtual void keyReleaseEvent(QKeyEvent *event) override{
            switch(event->key())
            {
            case Qt:: Key_Z:
            {
                m_Timer.stop();
            }
            default: qDebug() << "Other Key" << event->key();
            }
        }
    
    private slots:
        void moveSlot(){
            qDebug() << "Move" << QTime::currentTime();
    
    }
    };
    
    int main(int argc, char *argv[])
    {
    
        QApplication app(argc, argv);
    
        mWidget m;
        m.show();
        return app.exec();
    }
    
    #include "main.moc"
    

    works just fine:

    fcc88640-5201-483f-a20a-9f01f8dd5bae-image.png


Log in to reply