Я унаследовал QQuickWindow
и создал безрамное окно, которое можно перемещать с помощью перетаскивания. Внутри моего окна я положил Slider
элемент. Проблема в том, что Slider
перенаправляет события в родительское окно, и когда я пытаюсь изменить значение на слайдере, окно перемещается. Вот как это ведет себя:
Есть ли возможность заставить ползунок принимать события мыши, а не перенаправлять их в окно?
Вот мой код:
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);
}
Проблема в том, что QQuickWindow::mouseXxxEvent()
доставляет событие к элементу, которому оно принадлежит. Вы переопределили обработчики событий, сделайте свою обработку первый, а затем передать событие QQuickWindow
, Поэтому Слайдер получает события правильно после Вы сделали свою собственную обработку событий. Либо не вызывайте реализацию базового класса, если вы не хотите, чтобы оно доставляло событие элементам, либо сначала вызывайте реализацию базового класса и выполняйте пользовательскую обработку впоследствии, только если событие не было принято или так.
void MyWindow::mousePressEvent(QMouseEvent *e)
{
QQuickWindow::mousePressEvent(e);
if (!e->isAccepted() && e->button() == Qt::LeftButton)
{
m_initialMouseClickPos = e->pos();
m_move = true;
}
}
Слайдер не является виджетом, и он не обрабатывает события, как виджеты 🙁
Для реализации перетащите на QQuickWindow
, вы можете иметь область мыши в Qt Quick, позади элементов управления, и она перетаскивается вперед к вспомогательному объекту, который затем перетаскивает окно вокруг.