如何将 Qt 鼠标事件转发到 QQuickView?
Posted
技术标签:
【中文标题】如何将 Qt 鼠标事件转发到 QQuickView?【英文标题】:How to forward Qt Mouse event to QQuickView? 【发布时间】:2018-10-19 06:46:17 【问题描述】:在我的QMainWindow
中,我有一个QFrame
和一个QWidget
,它们包装了一个QQuickView
并通过qml
文件显示用户界面。
我正在尝试实现拖放功能,在QFrame
中按下鼠标并移动鼠标时,缩略图会一直跟随光标的位置,直到鼠标释放。鼠标释放将在QQuickView
内进行。
QQuickView
中的悬停事件没有问题,我可以成功获取悬停事件。当在QFrame
中按下鼠标然后将鼠标移动到QQuickView
时,就会出现问题,我无法在QQuickView
中获得任何鼠标事件。
左边是QFrame
,右边是QQuickView
。
单独悬停在QQuickView
:
在QFrame
中按下鼠标并在QQuickView
中移动鼠标:
任何鼠标事件都只能在鼠标释放后捕获。
这些是我目前所写的:
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】:原来我使用了错误的 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
希望这将能够帮助某人在路上。感谢raven-worx Qt Forum
的解决方案。
【讨论】:
以上是关于如何将 Qt 鼠标事件转发到 QQuickView?的主要内容,如果未能解决你的问题,请参考以下文章
退出时删除 QQuickView 会导致 Qt 应用程序冻结