如何将Qt鼠标事件转发到QQuickView?

时间:2018-10-19 06:46:17

标签: python qml pyqt5

在我的QMainWindow中,我有一个QFrame和一个QWidget,它们包装了一个QQuickView并通过一个qml文件显示了ui。

我正在尝试实现拖放功能,在QFrame中,通过鼠标向下和鼠标移动,缩略图始终跟随光标的位置,直到释放鼠标为止。鼠标释放将在QQuickView内进行。

QQuickView中的悬停事件没有问题,我可以成功获取悬停事件。当在QFrame中将鼠标向下移动,然后将鼠标移至QQuickView时,会出现问题,而我无法在QQuickView中获得任何鼠标事件。

左边是QFrame,右边是QQuickView

独立悬停在QQuickView中:

enter image description here

将鼠标移至QFrame中,然后将鼠标移至QQuickView中:

enter image description here

任何鼠标事件只能在释放鼠标后捕获。

这些是我到目前为止写的:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QFrame, QLabel, QGridLayout, QVBoxLayout
from PyQt5.QtCore import Qt, QMimeData, QUrl
from PyQt5.QtGui import QDrag, QPixmap
from PyQt5.QtQuick import QQuickView

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.centralWidget = QWidget(self)

        gridlayout = QGridLayout(self.centralWidget)
        gridlayout.setContentsMargins(0,0,0,0)
        gridlayout.setHorizontalSpacing(0)
        gridlayout.setVerticalSpacing(0)

        self.setCentralWidget(self.centralWidget)
        self.leftPanel = QVBoxLayout()
        self.rightPanel = QVBoxLayout()

        gridlayout.addLayout(self.leftPanel, 0, 0, 1, 1)
        gridlayout.addLayout(self.rightPanel, 0, 1, 1, 1)
        gridlayout.setSpacing(0)

        self.setStyleSheet("background:grey")
        self.resize(300, 200)
        self.show()

class Left(QFrame):
    def __init__(self):
        super().__init__()
        self.resize(500, 500)
        self.label = QLabel(self)
        self.label.resize(50, 50)

    def mouseMoveEvent(self, e):
        mimeData = QMimeData()
        drag = QDrag(self)
        self.thumbnail = QPixmap('./test.png').scaled(50, 50, Qt.KeepAspectRatio)
        drag.setPixmap(self.thumbnail)
        drag.setMimeData(mimeData)
        drag.exec_(Qt.MoveAction)

class Right(QQuickView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.rootContext().setContextProperty('Right', self)
        self.setSource(QUrl('./drag.qml'))
        self.setMinimumHeight(200)
        self.setMinimumWidth(150)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.leftPanel.addWidget(Left())
    main_window.rightPanel.addWidget(QWidget.createWindowContainer(Right()))
    app.exec_()

根据我从不同来源和Qt文档中所读到的内容,我想我必须将事件从QFrame转发到QQuickView或似乎有某种形式要处理的全局鼠标事件。

我该如何实现这一目标?

1 个答案:

答案 0 :(得分:0)

原来我使用了错误的qml元素。 DropArea中应使用qml

import QtQuick 2.7

Rectangle {

    id: root

    anchors.fill: parent
    color: 'transparent'

    Column {
        anchors.centerIn: parent
        Rectangle {
            width: 50
            height: 50
            color: 'red'
            anchors.horizontalCenter: parent.horizontalCenter
            DropArea {
                anchors.fill: parent
                onEntered: parent.color = 'blue'
                onExited: parent.color = 'red'
                onDropped: console.log('triggger this thing yo')
            }
        }
        Text {
            width: parent.parent.width
            text: 'on hover over box, color changes from red to blue and vice versa when hover out'
            wrapMode: Text.Wrap
            horizontalAlignment: Text.AlignHCenter
        }
    }
}

希望这可以帮助某人。归功于Qt Forum上的raven-worx来解决。