Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Unsolved keypressed and keyreleased

    General and Desktop
    6
    25
    651
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      genli last edited by genli

      So my problem is quite simple, only the solution I don't see it.
      I want when you press the "Z" key the robot will move forward. As long as you have not released the "Z" key, the robot should always move forward. Once you release the "Z" key the robot stops.
      The debug console shows me:
      Forward
      keyReleased
      Forward
      keyReleased
      Forward
      keyReleased
      What I would like it to display is as long as you press "Z" you get:
      Forward
      Forward
      Forward
      Then once we release "Z" we get:
      keyReleased
      I tried the timers and the autorepeat but they did not solve the problem

      jeremy_k J.Hilk CP71 3 Replies Last reply Reply Quote 0
      • jeremy_k
        jeremy_k @genli last edited by

        @genli said in keypressed and keyreleased:

        I tried the timers and the autorepeat but they did not solve the problem

        What does your code look like?

        Asking a question about code? http://eel.is/iso-c++/testcase/

        G 1 Reply Last reply Reply Quote 0
        • G
          genli @jeremy_k last edited by

          @jeremy_k
          void Robot::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 Robot::keyReleaseEvent(QKeyEvent*keyevent)
          {
          if (keyevent->isAutoRepeat() == true)
          {
          keyevent->ignore();
          }

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

          }

          KroMignon jeremy_k 3 Replies Last reply Reply Quote 0
          • KroMignon
            KroMignon @genli last edited by

            @genli The console debug output does not match with the code you post... So it is hard to understand what really happens.

            As side note: for me, the QKeyEvent::isAutoRepeat() only made sense in keyPressEvent(). In my comprehension, when autorepeate is set, then additional key pressed events are generated but no key released events.

            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

            G 1 Reply Last reply Reply Quote 0
            • G
              genli @KroMignon last edited by

              @KroMignon
              The debug console shows me:
              Forward
              keyReleased
              Forward
              keyReleased
              Forward
              keyReleased
              What I would like it to display is as long as you press "Z" you get:
              Forward
              Forward
              Forward
              Then once we release "Z" we get:
              keyReleased

              1 Reply Last reply Reply Quote 0
              • KroMignon
                KroMignon @genli last edited by KroMignon

                @genli said in keypressed and keyreleased:

                if (keyevent->isAutoRepeat() == true)
                {
                keyevent->ignore();
                }
                else {

                gpioPWM (12, 0);
                gpioPWM (13, 0);

                qDebug()<<"keyReleased";

                }

                I think this sould be:

                if(keyevent->key() == Qt::Key_Z)
                {
                    if (keyevent->isAutoRepeat() == true)
                    {
                        keyevent->ignore();
                        qDebug()<<"release ignored";
                    }
                    else
                    {
                        gpioPWM (12, 0);
                        gpioPWM (13, 0);
                        
                        qDebug()<<"keyReleased";
                    }
                }
                
                

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                1 Reply Last reply Reply Quote 0
                • J.Hilk
                  J.Hilk Moderators @genli last edited by J.Hilk

                  @genli
                  I actually answered a very similar question recently, can't find it any longer or I would have linked it, but I do still have the code example:

                  #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();
                  
                  }
                  };
                  

                  IIRC the idea was to send the command regularly through serial port or something. But the base idea of this should be the same, btw no autorepeat in this case!

                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct

                  Qt Needs YOUR vote: https://bugreports.qt.io/browse/QTQAINFRA-4121


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  G 1 Reply Last reply Reply Quote 0
                  • jeremy_k
                    jeremy_k @genli last edited by

                    @genli said in keypressed and keyreleased:

                    void Robot::keyReleaseEvent(QKeyEvent*keyevent)
                    {
                    if (keyevent->isAutoRepeat() == true)
                    {
                    keyevent->ignore();

                    Why are you ignoring the event? From the documentation:

                    Clearing the accept parameter indicates that the event receiver does not want the event. Unwanted events might be propagated to the parent widget.

                    Based on the problem description, I don't think the goal is to have something else handle the autorepeated press and release events. The widget accepting the key press needs to accept autorepeats, and use the lack of autorepeat to signal the beginning and end of the physical key press.

                    Asking a question about code? http://eel.is/iso-c++/testcase/

                    1 Reply Last reply Reply Quote 0
                    • G
                      genli @J.Hilk last edited by

                      @J-Hilk @KroMignon
                      thank you for your answer but it's still the same problem
                      my code with timers :
                      QObject::connect(&m_Timer, SIGNAL(timeout), this, SLOT(moveSlot));
                      MainWindow::MainWindow(QWidget *parent) :
                      QMainWindow(parent),
                      ui(new Ui::MainWindow)
                      {
                      ui->setupUi(this);
                      QObject::connect(&m_Timer, SIGNAL(timeout), this, SLOT(moveSlot));
                      m_Timer.setInterval(20);
                      }

                      MainWindow::~MainWindow()
                      {
                      delete ui;
                      }

                      void moveSlot()
                      {
                      qDebug() << "keyPressed";

                      }

                      void MainWindow::keyPressEvent(QKeyEvent*keyevent)
                      {
                      switch(keyevent->key())
                      {
                      case Qt:: Key_Z:
                      {
                      if(!m_Timer.isActive()){
                      m_Timer.start();
                      moveSlot();

                          }
                      
                      
                              }
                      

                      }
                      }

                      void MainWindow::keyReleaseEvent(QKeyEvent*keyevent)
                      {

                       switch(keyevent->key())
                              {
                              case Qt:: Key_Z:
                              {
                                  m_Timer.stop();
                                      qDebug() << "keyReleased ";
                                  
                                  
                              }
                      

                      }
                      }

                      1 Reply Last reply Reply Quote 0
                      • CP71
                        CP71 @genli last edited by CP71

                        @genli
                        Hi,
                        I suppose you have to manage more keys, not only Z.
                        A possible way to do this could be:

                        • Having a timer always active where you could have all your managements ( like a core )
                        • In keyPressEvent(QKeyEvent*keyevent) store the key pressed
                        • In keyReleaseEvent(QKeyEvent*keyevent) clear the variable where you store key-value

                        Below there is an example of a body that is called from your timer
                        void MyObject::core()
                        {
                        ...

                        //Moving manager
                        switch( keyPressed )
                        {
                        	case "Z": 
                        		move1();
                        		break;
                        
                        	case "A": 
                        		move2();
                        		break;
                        	...
                        
                                 default:
                                      stopMoving();
                                 break;
                        }
                        ...
                        

                        }

                        You must check if this solution is compatible with your project design

                        G 1 Reply Last reply Reply Quote 0
                        • G
                          genli @CP71 last edited by

                          @CP71 yes i have Z, S, Q, D for robot movement but i have question please is the stopMoving () function is in Keypressed ?

                          CP71 1 Reply Last reply Reply Quote 0
                          • CP71
                            CP71 @genli last edited by CP71

                            @genli
                            Yes,
                            in my idea in keyReleaseEvent you must clear keyPressed variable (for example keyPressed=""), so in the switch the program skips in default and you stop all moving.

                            It is clear that this logic could be improved to avoid doing the same operations

                            Is not key pressed but moving manager ;)

                            G 1 Reply Last reply Reply Quote 0
                            • G
                              genli @CP71 last edited by

                              @CP71 ok and how can i clear the keyPressed please

                              CP71 1 Reply Last reply Reply Quote 0
                              • CP71
                                CP71 @genli last edited by

                                @genli

                                void MyObject:: keyReleaseEvent(QKeyEvent*keyevent)
                                {
                                keyPressed = ""; //No key pressed = no moving, for this I insert stopMoving in switch in default
                                }

                                void MyObject::keyPressEvent(QKeyEvent*keyevent)
                                {
                                keyPressed = keyevent->key();
                                }

                                1 Reply Last reply Reply Quote 1
                                • G
                                  genli last edited by genli

                                  I changed the code but it's the same error :
                                  void Robot::keyPressEvent(QKeyEvent*keyevent)
                                  {
                                  if (keyevent->key() == Qt::Key_Z)
                                  {

                                     ui->forward_btn->pressed();
                                  

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

                                   if (keyevent->key() == Qt::Key_Z)
                                   {
                                       ui->forward_btn->released();
                                     }
                                  

                                  }
                                  any idea please ?

                                  CP71 1 Reply Last reply Reply Quote 0
                                  • CP71
                                    CP71 @genli last edited by

                                    @genli
                                    It seems you have 2 ways to moving the robot, via keyboard and via UI (pushbutton), haven't you?

                                    G 1 Reply Last reply Reply Quote 0
                                    • G
                                      genli @CP71 last edited by

                                      @CP71 yes that's it

                                      CP71 2 Replies Last reply Reply Quote 0
                                      • CP71
                                        CP71 @genli last edited by CP71

                                        @genli
                                        The idea is having one place where manage the moving.
                                        So my idea is the same:

                                        • having a timer always actived
                                        • defining a enum or defines for direction
                                        • in key event or pushbutton event store last moving selection.

                                        Only for example:

                                        enum Moving
                                        {
                                        enStop,
                                        enForward,
                                        enBack,
                                        enLeft,
                                        enRight
                                        }

                                        Moving moving;

                                        void MyObject::core()
                                        {
                                        ...
                                        //Moving manager

                                        switch( moving)
                                        {
                                        case enForward:
                                        move1();
                                        break;

                                        case enBack: 
                                        	move2();
                                        	break;
                                        ...
                                        
                                             default:
                                                  stopMoving();
                                             break;
                                        

                                        }
                                        ...
                                        }

                                        void MyObject:: keyReleaseEvent(QKeyEventkeyevent)
                                        {
                                        keyPressed = enStop;
                                        }
                                        void MyObject::keyPressEvent(QKeyEvent
                                        keyevent)
                                        {
                                        if ( keyEvent->key() == "S" )
                                        keyPressed = enForward;
                                        else if ( keyEvent->key() == "D" )
                                        keyPressed = enBack;
                                        ...
                                        }

                                        //for all 4 buttons write a code like this
                                        void MyObject::on_forward_btn_pressed()
                                        {
                                        keyPressed = enForward;
                                        ]

                                        void MyObject::on_forward_btn_relesed()
                                        {
                                        keyPressed = enStop;
                                        ]

                                        The above code could have error, I write in editor and not in QTCreator.

                                        For security the stopOperation I insert always in default.

                                        1 Reply Last reply Reply Quote 0
                                        • CP71
                                          CP71 @genli last edited by CP71

                                          @genli
                                          Obviously, you must correctly manage two commands that are opposite ( for example left and right simultaneously ).
                                          but switch'd already help you for this case ;)

                                          G 1 Reply Last reply Reply Quote 0
                                          • G
                                            genli @CP71 last edited by genli

                                            @CP71 the thing I can't understand is when I press Z:
                                            The debug console shows me:
                                            Forward
                                            keyReleased
                                            Forward
                                            keyReleased
                                            Forward
                                            keyReleased
                                            and when I keep pressing z and I press another button for example R or P the problem solved
                                            The debug console shows me:
                                            Forward
                                            Forward
                                            Forward
                                            how i can press a button on the keyboard using code ?

                                            artwaw CP71 2 Replies Last reply Reply Quote 0
                                            • First post
                                              Last post