J'ai hérité de QQuickWindow
et créé une fenêtre sans cadre qui peut être déplacée par glisser. Dans ma fenêtre, j'ai mis un élément Slider
. Le problème est que le Slider
transmet les événements à la fenêtre parente et quand j'essaie de changer la valeur sur le curseur, la fenêtre se déplace le long. Voici comment il se comporte:Rendre l'élément/le contrôle QML accepte les événements sans les transmettre au parent
Est-il possible de faire le curseur accepter les événements de souris et ne pas les transmettre à la fenêtre?
Voici mon code:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QUrl>
#include "mywindow.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<MyWindow>("mycustomlib", 1, 0, "MyWindow");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import mycustomlib 1.0
MyWindow {
width: 300
height: 180
visible: true
x: 250
y: 250
color: "beige"
Slider {
anchors.fill: parent
value: 0.5
}
}
mywindow.h
#ifndef MYWINDOW_H
#define MYWINDOW_H
#include <QQuickWindow>
class MyWindow : public QQuickWindow
{
Q_OBJECT
public:
MyWindow(QWindow *pParent = Q_NULLPTR);
protected:
virtual void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
virtual void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE;
private:
bool m_move;
QPoint m_initialMouseClickPos;
};
#endif // MYWINDOW_H
mywindow.cpp
#include "mywindow.h"
#include <QDebug>
#include <QCursor>
MyWindow::MyWindow(QWindow *pParent) :
QQuickWindow(pParent),
m_move(false)
{
setFlags(Qt::FramelessWindowHint);
}
void MyWindow::mouseMoveEvent(QMouseEvent *e)
{
if (m_move) {
const QPoint newMousePosition = e->pos() - m_initialMouseClickPos + position();
setPosition(newMousePosition);
}
QQuickWindow::mouseMoveEvent(e);
}
void MyWindow::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton)
{
m_initialMouseClickPos = e->pos();
m_move = true;
}
QQuickWindow::mousePressEvent(e);
}
void MyWindow::mouseReleaseEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton)
{
m_move = false;
}
QQuickWindow::mouseReleaseEvent(e);
}
Mais pouvez-vous me dire, pourquoi exactement le même code (sans votre correctif) mais en utilisant «QtWidgets» fonctionne bien? Pourquoi avec des widgets si je fais la manipulation en dernier, tout fonctionne bien? C'est à dire. si j'ai un QWidget et que je remplace tous ces gestionnaires d'événements et que je mets un QPushButton dessus tout fonctionne comme votre code (c'est-à-dire lorsque vous cliquez sur le QPushButton, l'événement ne parvient pas au widget parent). J'ai vraiment besoin de le savoir car il semble que le paradigme de propagation d'événements soit différent de widgets à qtquick. Merci! –
'QWindow' est le point d'entrée de niveau inférieur pour les événements du système de fenêtrage, et' QWidget' n'est pas un 'QWindow'. Le QWidgetWindow sous-jacent, qui achemine l'événement vers le QWidget approprié, est caché de vous.Même si vous pouvez y accéder via 'QWidget :: windowHandle()', avec les widgets, vous surchargez les gestionnaires d'événements au niveau de 'QWidget', pas au niveau de' QWindow'. Vous pouvez penser à la livraison d'événements 'QQuickWindow' similaire à celle de' QGraphicsView'. Les gestionnaires d'événements de la vue fournissent les événements à sa scène/éléments. – jpnurmi
Ou, pour le dire autrement, quand un 'QWindow' reçoit un événement souris, rien ne l'a encore traité. Lorsqu'un QWidget reçoit un événement souris, ses enfants ont déjà été traités et aucun d'eux ne l'a accepté. Si des enfants avaient accepté l'événement, le widget ne le recevrait pas. – jpnurmi