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

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