Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Manage widget focus
Forum Update on Monday, May 27th 2025

Manage widget focus

Scheduled Pinned Locked Moved Solved General and Desktop
focusqdial
5 Posts 2 Posters 1.1k Views
  • 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.
  • A Offline
    A Offline
    Agricola
    wrote on 13 Feb 2019, 12:01 last edited by
    #1

    I'm working on a C++ GUI. I use two QDial objects to control linear and angular velocity of a robot. Now I want to change the one Dial with up- and down-key, the other one with left- and right-key. How can I achieve that without having to use tab or mouseclicks to change the focus? I've tried to work with this function

    void MainWindow::keyPressEvent(QKeyEvent *event)
    {
        if(event->key() == Qt::Key_Up)
        {
            dial1->setFocus();
        }
        else if(event->key() == Qt::Key_Down)
        {
            dial1->setFocus();
        }
        else if(event->key() == Qt::Key_Left)
        {
             dial2->setFocus();
        }
        else if(event->key() == Qt::Key_Right)
        {
             dial2->setFocus();
        }
    }
    

    The Problem is, that the focus stays on the first widget focused. Do I have to set the focus back to the MainWindow after the keyboard input?
    Can someone suggest a clever way to solve this issue?

    Thanks a lot in advance!

    R 1 Reply Last reply 13 Feb 2019, 12:17
    0
    • A Agricola
      13 Feb 2019, 12:01

      I'm working on a C++ GUI. I use two QDial objects to control linear and angular velocity of a robot. Now I want to change the one Dial with up- and down-key, the other one with left- and right-key. How can I achieve that without having to use tab or mouseclicks to change the focus? I've tried to work with this function

      void MainWindow::keyPressEvent(QKeyEvent *event)
      {
          if(event->key() == Qt::Key_Up)
          {
              dial1->setFocus();
          }
          else if(event->key() == Qt::Key_Down)
          {
              dial1->setFocus();
          }
          else if(event->key() == Qt::Key_Left)
          {
               dial2->setFocus();
          }
          else if(event->key() == Qt::Key_Right)
          {
               dial2->setFocus();
          }
      }
      

      The Problem is, that the focus stays on the first widget focused. Do I have to set the focus back to the MainWindow after the keyboard input?
      Can someone suggest a clever way to solve this issue?

      Thanks a lot in advance!

      R Offline
      R Offline
      raven-worx
      Moderators
      wrote on 13 Feb 2019, 12:17 last edited by raven-worx
      #2

      @Agricola
      The following code increases/decreases the dial values no matter where the current focus is (as long as the mainwindow of course is active). The events are consumed for up/down/left/right keys and thus are not delivered to the target widget.
      Is this behavior what you want to achieve?

      qApp->installEventFilter( myFilter );
      ...
      bool MyFilter::eventFilter( QObject* watched, QEvent* event )
      {
          switch( event->type() )
          {
              case QEvent::KeyPress:
              {
                     QKeyEvent* ke = static_cast<QKeyEvent*>(event);
                     switch( ke->key() )
                     {
                            case Qt::Key_Up:
                                   dial1->triggerAction( QAbstractSlider::SliderSingleStepAdd );
                                   return true;
                            case Qt::Key_Down:
                                   dial1->triggerAction( QAbstractSlider::SliderSingleStepSub );
                                   return true;
                            case Qt::Key_Right:
                                   dial2->triggerAction( QAbstractSlider::SliderSingleStepAdd );
                                   return true;
                            case Qt::Key_Left:
                                   dial2->triggerAction( QAbstractSlider::SliderSingleStepSub );
                                   return true;
                     }
              }
          }
          return ParentClass::eventFilter( watched, event );
      }
      

      (untested)

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      A 1 Reply Last reply 14 Feb 2019, 09:03
      3
      • R raven-worx
        13 Feb 2019, 12:17

        @Agricola
        The following code increases/decreases the dial values no matter where the current focus is (as long as the mainwindow of course is active). The events are consumed for up/down/left/right keys and thus are not delivered to the target widget.
        Is this behavior what you want to achieve?

        qApp->installEventFilter( myFilter );
        ...
        bool MyFilter::eventFilter( QObject* watched, QEvent* event )
        {
            switch( event->type() )
            {
                case QEvent::KeyPress:
                {
                       QKeyEvent* ke = static_cast<QKeyEvent*>(event);
                       switch( ke->key() )
                       {
                              case Qt::Key_Up:
                                     dial1->triggerAction( QAbstractSlider::SliderSingleStepAdd );
                                     return true;
                              case Qt::Key_Down:
                                     dial1->triggerAction( QAbstractSlider::SliderSingleStepSub );
                                     return true;
                              case Qt::Key_Right:
                                     dial2->triggerAction( QAbstractSlider::SliderSingleStepAdd );
                                     return true;
                              case Qt::Key_Left:
                                     dial2->triggerAction( QAbstractSlider::SliderSingleStepSub );
                                     return true;
                       }
                }
            }
            return ParentClass::eventFilter( watched, event );
        }
        

        (untested)

        A Offline
        A Offline
        Agricola
        wrote on 14 Feb 2019, 09:03 last edited by
        #3

        @raven-worx
        Thanks a lot for the suggestion! I used your input to do some research in the docs as well but I somehow have problems making it work. Maybe you can have a look on what I've done so far?!

        I have added a new Class to my project that is derived from QObject and overrides the eventFilter()-Funktion.
        keypressfilter.cpp:

        #include "keypressfilter.h"
        
        KeyPressFilter::KeyPressFilter(QObject *parent) : QObject(parent)
        {
        
        }
        
        bool KeyPressFilter::eventFilter(QObject *obj, QEvent *event)
        {
            switch(event->type())
            {
                case QEvent::KeyPress:
                {
                    QKeyEvent* ke = static_cast<QKeyEvent*>(event);
                    switch(ke->key())
                    {
                        case Qt::Key_Enter:
                            emit enterKeySig();
                            return true;
                        case Qt::Key_Up:
                            emit upKeySig();
                            return true;
                        case Qt::Key_Down:
                            emit downKeySig();
                            return true;
                        case Qt::Key_Left:
                            emit leftKeySig();
                            return true;
                        case Qt::Key_Right:
                            emit rightKeySig();
                            return true;
                    }
                }
            }
            return QObject::eventFilter(obj, event);
        }
        

        I'm using Signals to make the changes to the dials in the MainWindow:
        mainwindow.cpp (excerpt):

        filter = new KeyPressFilter(this);
            connect(filter, SIGNAL(enterKeySig()), this, SLOT(enterKey()));
            connect(filter, SIGNAL(upKeySig()), this, SLOT(upKey()));
            connect(filter, SIGNAL(downKeySig()), this, SLOT(downKey()));
            connect(filter, SIGNAL(leftKeySig()), this, SLOT(leftKey()));
            connect(filter, SIGNAL(rightKeySig()), this, SLOT(rightKey()));
        

        The Slots to trigger the Dial:

        void MainWindow::upKey()
        {
            Dial->triggerAction(QAbstractSlider::SliderSingleStepAdd);
        }
        

        This way it doesn't seem to work; the Signals are not emitted.
        I've seen that it is possible to install the the filter in the App (that's what you did in your example as well right?), however I don't know how to convincingly call the Dials that way!?

        R 1 Reply Last reply 14 Feb 2019, 16:17
        0
        • A Agricola
          14 Feb 2019, 09:03

          @raven-worx
          Thanks a lot for the suggestion! I used your input to do some research in the docs as well but I somehow have problems making it work. Maybe you can have a look on what I've done so far?!

          I have added a new Class to my project that is derived from QObject and overrides the eventFilter()-Funktion.
          keypressfilter.cpp:

          #include "keypressfilter.h"
          
          KeyPressFilter::KeyPressFilter(QObject *parent) : QObject(parent)
          {
          
          }
          
          bool KeyPressFilter::eventFilter(QObject *obj, QEvent *event)
          {
              switch(event->type())
              {
                  case QEvent::KeyPress:
                  {
                      QKeyEvent* ke = static_cast<QKeyEvent*>(event);
                      switch(ke->key())
                      {
                          case Qt::Key_Enter:
                              emit enterKeySig();
                              return true;
                          case Qt::Key_Up:
                              emit upKeySig();
                              return true;
                          case Qt::Key_Down:
                              emit downKeySig();
                              return true;
                          case Qt::Key_Left:
                              emit leftKeySig();
                              return true;
                          case Qt::Key_Right:
                              emit rightKeySig();
                              return true;
                      }
                  }
              }
              return QObject::eventFilter(obj, event);
          }
          

          I'm using Signals to make the changes to the dials in the MainWindow:
          mainwindow.cpp (excerpt):

          filter = new KeyPressFilter(this);
              connect(filter, SIGNAL(enterKeySig()), this, SLOT(enterKey()));
              connect(filter, SIGNAL(upKeySig()), this, SLOT(upKey()));
              connect(filter, SIGNAL(downKeySig()), this, SLOT(downKey()));
              connect(filter, SIGNAL(leftKeySig()), this, SLOT(leftKey()));
              connect(filter, SIGNAL(rightKeySig()), this, SLOT(rightKey()));
          

          The Slots to trigger the Dial:

          void MainWindow::upKey()
          {
              Dial->triggerAction(QAbstractSlider::SliderSingleStepAdd);
          }
          

          This way it doesn't seem to work; the Signals are not emitted.
          I've seen that it is possible to install the the filter in the App (that's what you did in your example as well right?), however I don't know how to convincingly call the Dials that way!?

          R Offline
          R Offline
          raven-worx
          Moderators
          wrote on 14 Feb 2019, 16:17 last edited by raven-worx
          #4

          @Agricola
          are you calling qApp->installEventFilter()?
          Also you are using the old connection style, which might fail at runtime - check the console output for errors.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          A 1 Reply Last reply 15 Feb 2019, 06:43
          2
          • R raven-worx
            14 Feb 2019, 16:17

            @Agricola
            are you calling qApp->installEventFilter()?
            Also you are using the old connection style, which might fail at runtime - check the console output for errors.

            A Offline
            A Offline
            Agricola
            wrote on 15 Feb 2019, 06:43 last edited by
            #5

            @raven-worx
            Sorry if I wasn't specific enough. I solved the problem now; all I had to do was instantiating the filter and setting up the signal-slot-connections in the mainwindow.cpp and additionally (that's what I didn't grasp at first) calling

            app.installEventFilter(win->filter);
            

            in the main.cpp (win being the mainwindow object).

            Thanks a lot for your help!

            1 Reply Last reply
            0

            3/5

            14 Feb 2019, 09:03

            • Login

            • Login or register to search.
            3 out of 5
            • First post
              3/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved