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
QtWS25 Last Chance

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 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!

    raven-worxR 1 Reply Last reply
    0
    • A Agricola

      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!

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on 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
      3
      • raven-worxR raven-worx

        @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 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!?

        raven-worxR 1 Reply Last reply
        0
        • A Agricola

          @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!?

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on 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
          2
          • raven-worxR raven-worx

            @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 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

            • Login

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