我正在尝试通过重新实现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
之外时,鼠标坐标将按预期打印。除非按住鼠标按钮,否则没有任何反应。
答案 0 :(得分:11)
您的代码存在的问题是您需要明确地为所有小部件启用鼠标跟踪。您可以通过迭代主窗口小部件的所有子项,并为每个子窗口调用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_())
答案 1 :(得分:1)
上次更新2014/8/8 14:37 固定标签栏不是跟踪鼠标移动事件。 (你可以在我的代码中看到)
我还建议您实施QWidget.mouseMoveEvent (self, QMouseEvent)
。但不仅仅是根小部件,因为它跟踪有趣小部件的区域,因此您必须设置鼠标移动事件,所有小部件都可以在您的应用程序中跟踪您的。因此,创建委托方法将它们全部连接起来,如果你有任何信号形成鼠标移动事件,那么获取它的当前点。像这样;
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_())
此致
答案 2 :(得分:0)
我会尝试通过在调用QTabWidget构造函数时传递self来使您的QTabWidget成为MyWindow的逻辑子代。还为选项卡窗口小部件的子项传递父项,但将选项卡窗口小部件变量tabs
传递给它们各自的构造函数。如果没有像这样声明的子层次结构,事件可能无法正确转发到包含的小部件,因为它的" children"从qt场景图/事件队列的角度来看,它将被视为在您的类顶层绘制的单独小部件。
答案 3 :(得分:-1)
我遇到了同样的问题,并找到了答案here:
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)