[SOLVED] Why Q*Window Events are eaten by QML Item??
-
Hello All
I have a very simple application here, that create a
QQuickWindowUnder aQQuickItemeverything seems ok but whymousePressEventfunction does not call by theQQuickWindow?
Just we can seeQMLrelated messagesThanks 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); } -
Hello All
I have a very simple application here, that create a
QQuickWindowUnder aQQuickItemeverything seems ok but whymousePressEventfunction does not call by theQQuickWindow?
Just we can seeQMLrelated messagesThanks 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 ofMyItemtype, and it allow me to havemousePressEventfunction insideMyItemclass notMyWindowclass (however it behaves weird) - if we have
MouseAreainMyItemtype inqmlfile it doesn't let themousePressEventworks, I think it eats the event. - btw, I want to have
mousePressEventinMyWindowclass notMyItem
I think there are three layers here (top to bottom):
- qml MouseArea events (like onClicked)
- MyItem's mousePressEvent
- 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 -
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 ofMyItemtype, and it allow me to havemousePressEventfunction insideMyItemclass notMyWindowclass (however it behaves weird) - if we have
MouseAreainMyItemtype inqmlfile it doesn't let themousePressEventworks, I think it eats the event. - btw, I want to have
mousePressEventinMyWindowclass notMyItem
I think there are three layers here (top to bottom):
- qml MouseArea events (like onClicked)
- MyItem's mousePressEvent
- 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 topropagateComposedEvents, yes I did this, but does not work properly on composedEvents likeonClicked
but foronPressedandonReleasedimplementation inQMLcode it works finebut about my problem I had to call
MyWindowevents from theMyItemevents.
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
QQuickWindowI usedQObjectinsideQQuickItem - in
MyItemConstructor usedsetAcceptedMouseButtons(Qt::AllButtons); - calling fake
mouse***Eventfunction of QObject Subclass (here MyWindow fromMyItem's realmouse***Eventfunction)
Thanks
- instead of having
-
[SOLVED]
My problem is solve by these steps
- instead of having
QQuickWindowI usedQObjectinsideQQuickItem - in
MyItemConstructor usedsetAcceptedMouseButtons(Qt::AllButtons); - calling fake
mouse***Eventfunction of QObject Subclass (here MyWindow fromMyItem's realmouse***Eventfunction)
Thanks
- instead of having