Reputation: 3164
I inherited QQuickWindow
and created a frame-less window that can be moved by drag. Inside my window I put a Slider
element. The problem is that the Slider
forwards the events to the parent window and when I try to change the value on the slider, the window moves along. Here's how it behaves:
Is there a possibility to make the slider accept the mouse events and not forward them to the window?
Here's my 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);
}
Upvotes: 1
Views: 993
Reputation: 5836
The problem is that QQuickWindow::mouseXxxEvent()
delivers the event to the item it belongs to. You have overridden the event handlers, do your handling first, and then pass on the event to QQuickWindow
. Therefore the Slider receives the events right after you have done your custom event handling. Either don't call the base class implementation when you don`t want it to deliver the event to items, or call the base class implementation first and do your custom handling afterwards only if the event was not accepted or so.
void MyWindow::mousePressEvent(QMouseEvent *e)
{
QQuickWindow::mousePressEvent(e);
if (!e->isAccepted() && e->button() == Qt::LeftButton)
{
m_initialMouseClickPos = e->pos();
m_move = true;
}
}
Upvotes: 1
Reputation: 98425
The slider isn't a widget, and it doesn't process events like widgets do :(
To implement drag on a QQuickWindow
, you could have a mouse area in Qt Quick, behind the controls, and have it forward drags to a helper object that then drags the window around.
Upvotes: 1