使 QML Item/Control 接受事件,因此不会将它们转发给父级

Make QML Item/Control accept events thus not forwarding them to parent

我继承了QQuickWindow,创造了一个可以拖动移动的无框window。在我的 window 中,我放了一个 Slider 元素。问题是 Slider 将事件转发给父 window,当我尝试更改滑块上的值时,window 会随之移动。这是它的行为方式:

是否可以让滑块接受鼠标事件而不将它们转发给 window?

这是我的代码:

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 上实现拖动,您可以在 Qt Quick 中的控件后面有一个鼠标区域,然后将其向前拖动到辅助对象,然后将 window 拖到周围。

问题是 QQuickWindow::mouseXxxEvent() 将事件传递给它所属的项目。您已覆盖事件处理程序,先 进行处理,然后将事件传递给 QQuickWindow。因此,Slider 在您完成自定义事件处理后 收到事件。当您不希望它向项目传递事件时,不要调用基础 class 实现,或者先调用基础 class 实现,然后仅在事件不是时才进行自定义处理接受左右。

void MyWindow::mousePressEvent(QMouseEvent *e)
{
    QQuickWindow::mousePressEvent(e);

    if (!e->isAccepted() && e->button() == Qt::LeftButton)
    {
        m_initialMouseClickPos = e->pos();
        m_move = true;
    }

}