当光标在子widg上时,mouseMoveEvent没有启动

2024-06-25 23:01:11 发布

您现在位置:Python中文网/ 问答频道 /正文

当鼠标在QWidget内移动时,我试图通过重新实现QWidget::mouseMoveEvent()来捕获光标坐标。启用鼠标跟踪后,当我在主小部件周围移动光标时,将生成鼠标移动事件。但是,当光标放在子小部件上时,鼠标移动事件将停止。

鼠标按下/释放事件在光标位于同一子窗口小部件上时工作,如果按住鼠标按钮,则移动事件将正确触发。我也试过在孩子们身上启用鼠标跟踪,但似乎没什么区别。当鼠标位于子小部件上时,如何触发鼠标移动事件?

下面是一个最小的工作示例,演示了该问题:

import sys
from PyQt4 import QtCore, QtGui

class MyWindow(QtGui.QWidget) :
    def __init__(self):
        QtGui.QWidget.__init__(self)
        tabs = QtGui.QTabWidget()
        tab1 = QtGui.QWidget()
        tab2 = QtGui.QWidget()
        tabs.addTab(tab1, "Tab 1")
        tabs.addTab(tab2, "Tab 2")
        layout = QtGui.QVBoxLayout()
        layout.addWidget(tabs)
        self.setLayout(layout)
        self.setMouseTracking(True)

    def mouseMoveEvent(self, event):
        print 'mouseMoveEvent: x=%d, y=%d' % (event.x(), event.y())


app = QtGui.QApplication(sys.argv)
window = MyWindow()
window.setFixedSize(640, 480)
window.show()
sys.exit(app.exec_())

当鼠标移到QTabWidget之外时,鼠标坐标按预期打印。在里面,除非按住鼠标键,否则什么都不会发生。


Tags: importselfevent部件sys事件鼠标window
3条回答

我将尝试在调用QTabWidget构造函数时通过传递self使您的QTabWidget成为MyWindow的逻辑子级。同时为tab小部件的子部件传递父部件,但将tab小部件变量tabs传递给它们各自的构造函数。如果没有这样声明的子层次结构,事件可能无法正确地转发到包含的小部件,因为从qt场景图/事件队列的角度来看,它的“子”将被视为在类顶部绘制的单独小部件。

代码的问题是需要显式地为所有小部件启用鼠标跟踪。您可以通过迭代主小部件的所有子部件,并为每个子部件调用setMouseTracking(True)来完成此操作。在这里,我重写了setMouseTracking()来实现这一点:

import sys
from PyQt4 import QtCore, QtGui

class MyWindow(QtGui.QWidget) :
    def __init__(self):
        QtGui.QWidget.__init__(self)
        tabs = QtGui.QTabWidget()
        tab1 = QtGui.QWidget()
        tab2 = QtGui.QWidget()
        tabs.addTab(tab1, "Tab 1")
        tabs.addTab(tab2, "Tab 2")
        layout = QtGui.QVBoxLayout()
        layout.addWidget(tabs)
        self.setLayout(layout)
        self.setMouseTracking(True)

    def setMouseTracking(self, flag):
        def recursive_set(parent):
            for child in parent.findChildren(QtCore.QObject):
                try:
                    child.setMouseTracking(flag)
                except:
                    pass
                recursive_set(child)
        QtGui.QWidget.setMouseTracking(self, flag)
        recursive_set(self)

    def mouseMoveEvent(self, event):
        print 'mouseMoveEvent: x=%d, y=%d' % (event.x(), event.y())


app = QtGui.QApplication(sys.argv)
window = MyWindow()
window.setFixedSize(640, 480)
window.show()
sys.exit(app.exec_())

上次更新时间2014年8月19日14:37固定选项卡栏不是跟踪鼠标移动事件。(你可以在我的代码中看到)


我还建议像您这样实现QWidget.mouseMoveEvent (self, QMouseEvent)。但不仅因为根小部件跟踪有趣小部件的区域,所以您必须设置鼠标移动事件所有小部件都可以在您的应用程序中跟踪您。所以,创建delegate方法来连接它们,如果您有来自mouse move事件的任何信号,则获取当前的鼠标点。像这样

import sys
from PyQt4 import QtGui

class QCustomWidget (QtGui.QWidget):
    def __init__ (self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        self.myQTabWidget = QtGui.QTabWidget(self)
        self.my1QWidget   = QtGui.QWidget()
        self.my2QWidget   = QtGui.QWidget()
        self.myQTabWidget.addTab(self.my1QWidget, 'Tab 1')
        self.myQTabWidget.addTab(self.my2QWidget, 'Tab 2')
        myQLayout = QtGui.QVBoxLayout()
        myQLayout.addWidget(self.myQTabWidget)
        self.setLayout(myQLayout)
        self.setMouseMoveEventDelegate(self)
        self.setMouseMoveEventDelegate(self.myQTabWidget)
        self.setMouseMoveEventDelegate(self.myQTabWidget.tabBar())
        self.setMouseMoveEventDelegate(self.my1QWidget)
        self.setMouseMoveEventDelegate(self.my2QWidget)

    def setMouseMoveEventDelegate (self, setQWidget):
        def subWidgetMouseMoveEvent (eventQMouseEvent):
            currentQPoint = self.mapFromGlobal(QtGui.QCursor.pos())
            print currentQPoint.x(), currentQPoint.y()
            QtGui.QWidget.mouseMoveEvent(setQWidget, eventQMouseEvent)
        setQWidget.setMouseTracking(True)
        setQWidget.mouseMoveEvent = subWidgetMouseMoveEvent

appQApplication = QtGui.QApplication(sys.argv)
windowQCustomWidget = QCustomWidget()
windowQCustomWidget.setFixedSize(640, 480)
windowQCustomWidget.show()
sys.exit(appQApplication.exec_())

谨致问候

相关问题 更多 >