Заставьте QML Item / Control принимать события, не передавая их родителю

Я унаследовал 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);
}

1

Решение

Проблема в том, что 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;
}

}
1

Другие решения

Слайдер не является виджетом, и он не обрабатывает события, как виджеты 🙁

Для реализации перетащите на QQuickWindow, вы можете иметь область мыши в Qt Quick, позади элементов управления, и она перетаскивается вперед к вспомогательному объекту, который затем перетаскивает окно вокруг.

1

По вопросам рекламы [email protected]