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. QWidget objects with Qt::Window flag set do not pass on ignored events
Forum Updated to NodeBB v4.3 + New Features

QWidget objects with Qt::Window flag set do not pass on ignored events

Scheduled Pinned Locked Moved Unsolved General and Desktop
20 Posts 3 Posters 6.0k Views 2 Watching
  • 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
    amdreallyfast
    wrote on 7 Oct 2016, 03:04 last edited by
    #7

    Sorry for the delay.

    Here's the basic program: The main window has a push button that summons a ChildWindow object (QOpenGLWidget derivative) with the Qt::Window flag set. Pressing any key causes the ChildWindow's keyPressEvent(...) to print a message to the console, and then the event is ignored. The main window is the ChildWindow's parent, so the event should pass on to the main window. But it doesn't. The event stops at the ChildWindow.

    Did I miss something or is this a bug?

    Here's my code.

    .pro (note the "CONFIG+= console" at the end)

    QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = WidgetsEventsNotPropogating
    TEMPLATE = app
    
    
    SOURCES += main.cpp\
            mainwindow.cpp \
        childwindow.cpp
    
    HEADERS  += mainwindow.h \
        childwindow.h
    
    FORMS    += mainwindow.ui
    
    CONFIG += console
    

    mainwindow.ui XML

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>400</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralWidget">
       <widget class="QPushButton" name="pushButton">
        <property name="geometry">
         <rect>
          <x>140</x>
          <y>100</y>
          <width>171</width>
          <height>81</height>
         </rect>
        </property>
        <property name="text">
         <string>PushButton</string>
        </property>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menuBar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>400</width>
         <height>21</height>
        </rect>
       </property>
      </widget>
      <widget class="QToolBar" name="mainToolBar">
       <attribute name="toolBarArea">
        <enum>TopToolBarArea</enum>
       </attribute>
       <attribute name="toolBarBreak">
        <bool>false</bool>
       </attribute>
      </widget>
      <widget class="QStatusBar" name="statusBar"/>
     </widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections/>
    </ui>
    

    mainwindow.h

    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
        void keyPressEvent(QKeyEvent *e) override;
    
    private:
        Ui::MainWindow *ui;
    };
    

    mainwindow.cpp

    #include <qevent.h>
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "childwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        printf("MainWindow::on_pushButton_clicked()\n");
        ChildWindow *cw = new ChildWindow(this, Qt::Window);
        cw->show();
    }
    
    void MainWindow::keyPressEvent(QKeyEvent *e)
    {
        printf("MainWindow::keyPressEvent(QKeyEvent *e)\n");
        e->accept();
    }
    

    childwindow.h

    #include <qopenglwidget.h>
    
    class ChildWindow : public QOpenGLWidget
    {
        Q_OBJECT
    
    public:
        ChildWindow(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags());
    
    protected:
        void keyPressEvent(QKeyEvent *e);
    };
    

    childwindow.cpp

    #include <qevent.h>
    
    #include "childwindow.h"
    
    ChildWindow::ChildWindow(QWidget *parent, Qt::WindowFlags f) :
        QOpenGLWidget(parent, f)
    {
    }
    
    void ChildWindow::keyPressEvent(QKeyEvent *e)
    {
        printf("ChildWindow::keyPressEvent(QKeyEvent *e)\n");
        e->ignore();
    }
    
    K 1 Reply Last reply 7 Oct 2016, 17:43
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on 7 Oct 2016, 16:58 last edited by mrjj 10 Jul 2016, 17:07
      #8

      Hi!
      I still don't think it's a bug but intended behaviour. However, in the meantime I came up with another workaround which is much prettier than the ones before: Just do the following:

      #include <QApplication>
      
      // ...
      
      void ChildWindow::keyPressEvent(QKeyEvent *e)
      {
          printf("ChildWindow::keyPressEvent(QKeyEvent *e)\n");
          QApplication::sendEvent(parentWidget(), e);
          e->ignore();
      }
      
      1 Reply Last reply
      2
      • A amdreallyfast
        7 Oct 2016, 03:04

        Sorry for the delay.

        Here's the basic program: The main window has a push button that summons a ChildWindow object (QOpenGLWidget derivative) with the Qt::Window flag set. Pressing any key causes the ChildWindow's keyPressEvent(...) to print a message to the console, and then the event is ignored. The main window is the ChildWindow's parent, so the event should pass on to the main window. But it doesn't. The event stops at the ChildWindow.

        Did I miss something or is this a bug?

        Here's my code.

        .pro (note the "CONFIG+= console" at the end)

        QT       += core gui
        
        greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
        
        TARGET = WidgetsEventsNotPropogating
        TEMPLATE = app
        
        
        SOURCES += main.cpp\
                mainwindow.cpp \
            childwindow.cpp
        
        HEADERS  += mainwindow.h \
            childwindow.h
        
        FORMS    += mainwindow.ui
        
        CONFIG += console
        

        mainwindow.ui XML

        <?xml version="1.0" encoding="UTF-8"?>
        <ui version="4.0">
         <class>MainWindow</class>
         <widget class="QMainWindow" name="MainWindow">
          <property name="geometry">
           <rect>
            <x>0</x>
            <y>0</y>
            <width>400</width>
            <height>300</height>
           </rect>
          </property>
          <property name="windowTitle">
           <string>MainWindow</string>
          </property>
          <widget class="QWidget" name="centralWidget">
           <widget class="QPushButton" name="pushButton">
            <property name="geometry">
             <rect>
              <x>140</x>
              <y>100</y>
              <width>171</width>
              <height>81</height>
             </rect>
            </property>
            <property name="text">
             <string>PushButton</string>
            </property>
           </widget>
          </widget>
          <widget class="QMenuBar" name="menuBar">
           <property name="geometry">
            <rect>
             <x>0</x>
             <y>0</y>
             <width>400</width>
             <height>21</height>
            </rect>
           </property>
          </widget>
          <widget class="QToolBar" name="mainToolBar">
           <attribute name="toolBarArea">
            <enum>TopToolBarArea</enum>
           </attribute>
           <attribute name="toolBarBreak">
            <bool>false</bool>
           </attribute>
          </widget>
          <widget class="QStatusBar" name="statusBar"/>
         </widget>
         <layoutdefault spacing="6" margin="11"/>
         <resources/>
         <connections/>
        </ui>
        

        mainwindow.h

        #include <QMainWindow>
        
        namespace Ui {
        class MainWindow;
        }
        
        class MainWindow : public QMainWindow
        {
            Q_OBJECT
        
        public:
            explicit MainWindow(QWidget *parent = 0);
            ~MainWindow();
        
        private slots:
            void on_pushButton_clicked();
            void keyPressEvent(QKeyEvent *e) override;
        
        private:
            Ui::MainWindow *ui;
        };
        

        mainwindow.cpp

        #include <qevent.h>
        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include "childwindow.h"
        
        MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            ui(new Ui::MainWindow)
        {
            ui->setupUi(this);
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        
        void MainWindow::on_pushButton_clicked()
        {
            printf("MainWindow::on_pushButton_clicked()\n");
            ChildWindow *cw = new ChildWindow(this, Qt::Window);
            cw->show();
        }
        
        void MainWindow::keyPressEvent(QKeyEvent *e)
        {
            printf("MainWindow::keyPressEvent(QKeyEvent *e)\n");
            e->accept();
        }
        

        childwindow.h

        #include <qopenglwidget.h>
        
        class ChildWindow : public QOpenGLWidget
        {
            Q_OBJECT
        
        public:
            ChildWindow(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags());
        
        protected:
            void keyPressEvent(QKeyEvent *e);
        };
        

        childwindow.cpp

        #include <qevent.h>
        
        #include "childwindow.h"
        
        ChildWindow::ChildWindow(QWidget *parent, Qt::WindowFlags f) :
            QOpenGLWidget(parent, f)
        {
        }
        
        void ChildWindow::keyPressEvent(QKeyEvent *e)
        {
            printf("ChildWindow::keyPressEvent(QKeyEvent *e)\n");
            e->ignore();
        }
        
        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 7 Oct 2016, 17:43 last edited by kshegunov 10 Jul 2016, 17:43
        #9

        Override QWidget::event and inspect what the state of the event is after the call to the superclass' method. E.g:

        #include <qopenglwidget.h>
        
        class ChildWindow : public QOpenGLWidget
        {
            Q_OBJECT
        
        public:
            // ...
            bool event(QEvent * e) override
            {
                bool result = QOpenGLWidget::event(e);
                qDebug() << result << e->isAccepted();
        
                return result;
            }
        };
        

        Then report your findings here. In principle QWidget::event should propagate the event up the object tree. While I don't believe this should be dependent on the window flags, I'm not sure.

        Kind regards.

        Read and abide by the Qt Code of Conduct

        ? 2 Replies Last reply 7 Oct 2016, 17:48
        1
        • K kshegunov
          7 Oct 2016, 17:43

          Override QWidget::event and inspect what the state of the event is after the call to the superclass' method. E.g:

          #include <qopenglwidget.h>
          
          class ChildWindow : public QOpenGLWidget
          {
              Q_OBJECT
          
          public:
              // ...
              bool event(QEvent * e) override
              {
                  bool result = QOpenGLWidget::event(e);
                  qDebug() << result << e->isAccepted();
          
                  return result;
              }
          };
          

          Then report your findings here. In principle QWidget::event should propagate the event up the object tree. While I don't believe this should be dependent on the window flags, I'm not sure.

          Kind regards.

          ? Offline
          ? Offline
          A Former User
          wrote on 7 Oct 2016, 17:48 last edited by
          #10

          @kshegunov As far as I can tell the docs mention nothing about this. On the other hand google finds a handful of people stuggling with this dating back half a decade or so. Maybe it's time to read some code :-|

          K 1 Reply Last reply 7 Oct 2016, 18:03
          1
          • K kshegunov
            7 Oct 2016, 17:43

            Override QWidget::event and inspect what the state of the event is after the call to the superclass' method. E.g:

            #include <qopenglwidget.h>
            
            class ChildWindow : public QOpenGLWidget
            {
                Q_OBJECT
            
            public:
                // ...
                bool event(QEvent * e) override
                {
                    bool result = QOpenGLWidget::event(e);
                    qDebug() << result << e->isAccepted();
            
                    return result;
                }
            };
            

            Then report your findings here. In principle QWidget::event should propagate the event up the object tree. While I don't believe this should be dependent on the window flags, I'm not sure.

            Kind regards.

            ? Offline
            ? Offline
            A Former User
            wrote on 7 Oct 2016, 17:53 last edited by
            #11

            @kshegunov And yes, the base class implementation returns true although the event hasn't been accepted. So, to me, still looks as this happens on purpose.

            K 1 Reply Last reply 7 Oct 2016, 18:00
            1
            • ? A Former User
              7 Oct 2016, 17:53

              @kshegunov And yes, the base class implementation returns true although the event hasn't been accepted. So, to me, still looks as this happens on purpose.

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 7 Oct 2016, 18:00 last edited by
              #12

              Yes, because of this call and ultimately this. It appears key press events aren't propagated at all. Could someone please confirm that last part, and make sure that the window flags doesn't change behavior?

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              1
              • ? A Former User
                7 Oct 2016, 17:48

                @kshegunov As far as I can tell the docs mention nothing about this. On the other hand google finds a handful of people stuggling with this dating back half a decade or so. Maybe it's time to read some code :-|

                K Offline
                K Offline
                kshegunov
                Moderators
                wrote on 7 Oct 2016, 18:03 last edited by kshegunov 10 Jul 2016, 18:03
                #13

                @Wieland said in QWidget objects with Qt::Window flag set do not pass on ignored events:

                As far as I can tell the docs mention nothing about this.

                They do[1, 2], but it's really vague.

                Read and abide by the Qt Code of Conduct

                ? 1 Reply Last reply 7 Oct 2016, 18:06
                1
                • K kshegunov
                  7 Oct 2016, 18:03

                  @Wieland said in QWidget objects with Qt::Window flag set do not pass on ignored events:

                  As far as I can tell the docs mention nothing about this.

                  They do[1, 2], but it's really vague.

                  ? Offline
                  ? Offline
                  A Former User
                  wrote on 7 Oct 2016, 18:06 last edited by
                  #14

                  @kshegunov I meant it doesn't say anything about event propagation stopping on window boundaries.

                  K 1 Reply Last reply 7 Oct 2016, 18:10
                  0
                  • ? A Former User
                    7 Oct 2016, 18:06

                    @kshegunov I meant it doesn't say anything about event propagation stopping on window boundaries.

                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 7 Oct 2016, 18:10 last edited by
                    #15

                    @Wieland said in QWidget objects with Qt::Window flag set do not pass on ignored events:
                    I see. Have you confirmed this is because of the flag? I'm not as convinced. I didn't see anything in the code to hint that the flags have any reflection on events propagation. I'd expect the same behavior (key presses not bubbling up) for any window flag that may be passed.

                    Read and abide by the Qt Code of Conduct

                    ? 1 Reply Last reply 7 Oct 2016, 18:52
                    0
                    • K kshegunov
                      7 Oct 2016, 18:10

                      @Wieland said in QWidget objects with Qt::Window flag set do not pass on ignored events:
                      I see. Have you confirmed this is because of the flag? I'm not as convinced. I didn't see anything in the code to hint that the flags have any reflection on events propagation. I'd expect the same behavior (key presses not bubbling up) for any window flag that may be passed.

                      ? Offline
                      ? Offline
                      A Former User
                      wrote on 7 Oct 2016, 18:52 last edited by A Former User 10 Jul 2016, 19:08
                      #16

                      @kshegunov Flags have some effect, e.g. the popup flag makes the window close on key pressed and then the event is accepted; but otherwise: no. The keyPressEvent() function doesn't do anything but ignore the event and then in the end event() returns true. Maybe there's more magic in the event dispatcher, but the code is quite hard to read.

                      Edit: Key event propagation actually does work as expected with flag Qt:Widget on the child and when the event is being ignored. But I can't tell where the magic happens :-/

                      1 Reply Last reply
                      0
                      • ? Offline
                        ? Offline
                        A Former User
                        wrote on 7 Oct 2016, 19:57 last edited by
                        #17

                        Sorry, I give up. :-/

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          amdreallyfast
                          wrote on 10 Oct 2016, 02:04 last edited by
                          #18

                          Thanks anyway.

                          BTW, @kshegunov , I did experiment with overriding the Qt::event(...) method, and MainWindow was still getting nothing as long as the child widget was a window. Then I made the child not spawn as a window (instead as a sub-widget) and the ignored event was passed on just fine. For the time being, I'll just click on MainWindow and hit Esc. to close down the program. I don't want to deal with connecting everyone to the MainWindow via signal and slot just to tell it to close.

                          K 1 Reply Last reply 10 Oct 2016, 13:47
                          0
                          • A amdreallyfast
                            10 Oct 2016, 02:04

                            Thanks anyway.

                            BTW, @kshegunov , I did experiment with overriding the Qt::event(...) method, and MainWindow was still getting nothing as long as the child widget was a window. Then I made the child not spawn as a window (instead as a sub-widget) and the ignored event was passed on just fine. For the time being, I'll just click on MainWindow and hit Esc. to close down the program. I don't want to deal with connecting everyone to the MainWindow via signal and slot just to tell it to close.

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 10 Oct 2016, 13:47 last edited by kshegunov 10 Oct 2016, 13:47
                            #19

                            @amdreallyfast said in QWidget objects with Qt::Window flag set do not pass on ignored events:

                            I did experiment with overriding the Qt::event(...) method, and MainWindow was still getting nothing as long as the child widget was a window. Then I made the child not spawn as a window (instead as a sub-widget) and the ignored event was passed on just fine.

                            My best advice is to ask in the mailing list if this is intentional, and if it's not to file a bug report.

                            Read and abide by the Qt Code of Conduct

                            A 1 Reply Last reply 10 Oct 2016, 14:42
                            0
                            • K kshegunov
                              10 Oct 2016, 13:47

                              @amdreallyfast said in QWidget objects with Qt::Window flag set do not pass on ignored events:

                              I did experiment with overriding the Qt::event(...) method, and MainWindow was still getting nothing as long as the child widget was a window. Then I made the child not spawn as a window (instead as a sub-widget) and the ignored event was passed on just fine.

                              My best advice is to ask in the mailing list if this is intentional, and if it's not to file a bug report.

                              A Offline
                              A Offline
                              amdreallyfast
                              wrote on 10 Oct 2016, 14:42 last edited by
                              #20

                              @kshegunov

                              By "mailing list" do you mean the "interest" mailing list? I've already asked one question there and gotten no replies. It is quite busy with "how do I do this?" messages instead of unexpected behavior, so I don't know if I'm asking the right group.

                              1 Reply Last reply
                              0

                              16/20

                              7 Oct 2016, 18:52

                              • Login

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