Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[SOLVED] Why Q*Window Events are eaten by QML Item??



  • Hello All

    I have a very simple application here, that create a QQuickWindow Under a QQuickItem everything seems ok but why mousePressEvent function does not call by the QQuickWindow ?
    Just we can see QML related messages

    Thanks for any idea

    ---------------

    main.cpp

    #include "view.h"
    
    #include <QtQml/QQmlApplicationEngine>
    #include <QtWidgets/QApplication>
    
    int main(int argc, char **argv)
    {
      QApplication app(argc, argv);
      QQmlApplicationEngine engine;
    
      qmlRegisterType<MyItem>("Sample", 1, 0, "MyItem");
    
      engine.load(QUrl("qrc:/main.qml"));
      if (engine.rootObjects().isEmpty())
        return -1;
    
      return app.exec();
    }
    
    ---------------

    main.qml

    import QtQuick 2.12
    import QtQuick.Controls 2.13
    import QtQuick.Window 2.12
    import Sample 1.0
    
    Window {
        id: main
        width: 600
        height: 600
        visible: true
        
        SplitView {
            id: splitView
            anchors.fill: parent
            orientation: Qt.Horizontal
    
            handle: Rectangle {
                implicitWidth: 4
                implicitHeight: 4
                color: SplitHandle.pressed ? "#81e889"
                    : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6")
            }
    
            MyItem {
                id: lefty
                implicitWidth: 300
                implicitHeight: 300
                MouseArea
                {
                    anchors.fill: parent;
                    onClicked:
                    {
                        console.log("Lefty");
                    }
                }
            }
    
            Item {
                id: righty
                implicitWidth: 300
                implicitHeight: 300
                Rectangle {
                    anchors.fill: parent
                    color: "gray"
                    MouseArea
                    {
                        anchors.fill: parent;
                        onClicked:
                        {
                            console.log("Righty");
                        }
                    }                  
                }
            }   
        }
    }
    
    ---------------

    view.h

    #ifndef VIEW_H
    #define VIEW_H
    
    #include <QtQuick/QQuickItem>
    #include <QtQuick/QQuickWindow>
    
    class MyWindow;
    
    // ----------------------------------
    class MyItem : public QQuickItem
    {
      Q_OBJECT
    
    public:
      explicit MyItem();
      ~MyItem();
    
    private:
      MyWindow *win;
    };
    
    // ----------------------------------
    class MyWindow : public QQuickWindow
    {
      Q_OBJECT
    
    public:
      explicit MyWindow();
      ~MyWindow();
    
    protected:
      void mousePressEvent(QMouseEvent *event) override;
    };
    
    #endif // VIEW_H
    
    ---------------

    view.cpp

    #include "view.h"
    
    MyItem::MyItem()
        : win(nullptr)
    {
      if (!win)
      {
        win = new MyWindow();
      }
    }
    
    MyItem::~MyItem()
    {
      delete win;
      win = nullptr;
    }
    
    // ----------------------------------------
    MyWindow::MyWindow()
    {
    }
    
    MyWindow::~MyWindow()
    {
    }
    
    void MyWindow::mousePressEvent(QMouseEvent *event)
    {
      qDebug() << "mousePressEvent";
      QQuickWindow::mousePressEvent(event);
    }
    


  • @madoodia Hello, like written in documentation, you have to enable mouse before ==> QQuickItem::acceptedMouseButtons()

    The default value is Qt::NoButton; that is, no mouse buttons are accepted.
    If an item does not accept the mouse button for a particular mouse event, the mouse event will not be delivered to the item and will be delivered to the next item in the item hierarchy instead.

    For example add setCursor(Qt::AllButtons) in your constructor.



  • thanks @KroMignon

    there are a few things here

    • setCursor is for the shape of the cursor so don't think is solve the problem
    • I used setAcceptedMouseButtons(Qt::LeftButton); in constructor of MyItem type, and it allow me to have mousePressEvent function inside MyItem class not MyWindow class (however it behaves weird)
    • if we have MouseArea in MyItem type in qml file it doesn't let the mousePressEvent works, I think it eats the event.
    • btw, I want to have mousePressEvent in MyWindow class not MyItem

    I think there are three layers here (top to bottom):

    1. qml MouseArea events (like onClicked)
    2. MyItem's mousePressEvent
    3. MyWindow's mousePressEvent

    I want to have first and third simultaneously, and don't know which one override or eat the others, and totally this is possible or not!!

    I hope it makes sense.
    btw, I'm still testing



  • @madoodia I apologize, I have not take care about all you have written and read your post too fast... Sorry about that.

    For the MouseArea, you have to say to it to not consume the mouse events:

    MouseArea {
       anchors.fill: parent
        propagateComposedEvents: true
        onClicked: {
            console.log("clicked!!")
            mouse.accepted = false // ==> to propagate this event to lower level
        }
    }
    

    This should solve your issue, take a look at propagateComposedEvents for more details.



  • thank @KroMignon
    related to propagateComposedEvents, yes I did this, but does not work properly on composedEvents like onClicked
    but for onPressed and onReleased implementation in QML code it works fine

    but about my problem I had to call MyWindow events from the MyItem events.
    solved it a little bit.

    If I get the result I am looking for will update the post



  • [SOLVED]

    My problem is solve by these steps

    • instead of having QQuickWindow I used QObject inside QQuickItem
    • in MyItem Constructor used setAcceptedMouseButtons(Qt::AllButtons);
    • calling fake mouse***Event function of QObject Subclass (here MyWindow from MyItem's real mouse***Event function)

    Thanks


  • Lifetime Qt Champion

    @madoodia Please mark as solved (see "Topic Tools" at right bottom side).


Log in to reply