PyQt4 无鼠标点击的 MouseMove 事件

10 投票
4 回答
23045 浏览
提问于 2025-04-17 04:40

我需要在用户鼠标移动到图形界面上时捕捉到这个动作,但不想在他们按住鼠标按钮的时候捕捉到(因为那样会有不同的反应)。

我找不到什么方便的方法来做到这一点,除了定期检查鼠标的位置,然后和之前的位置进行对比……这听起来太麻烦了。

鼠标移动事件(mouseMoveEvent)只有在按住左键的时候才会被调用,当然如果这个控件开启了“鼠标追踪”功能就另当别论了。不过对我来说,鼠标追踪不是一个选项,因为当鼠标移动和按住左键时,图形界面的反应必须是不同的。

有没有什么内置的方法可以做到这一点?
(或者有什么聪明的主意吗?)

比如说:有没有办法随时检查左键是否被按下?
或者有没有可以应用于矩形区域(坐标)的“鼠标悬停”事件?

非常感谢。


操作系统:Windows 7(32位)
编程语言:Python 2.7
使用的库:PyQt4

4 个回答

2

看起来你对 mouseTracking 的作用有些误解。它的作用只是让 mouseMoveEvent 这个事件被触发,仅此而已。换句话说,这正是你需要的功能。

你可以查看事件的 buttons() 方法,看看有没有按下任何按钮:

对于鼠标移动事件,这里指的是所有被按下的按钮。

3

正如大家所说,正确的方法是对这个小部件调用 setMouseTracking(True)。我想补充的是,做了这个之后,你可以通过以下方式区分鼠标移动和鼠标拖动:

def mouseMoveEvent(self, event):
    if event.buttons() == QtCore.Qt.NoButton:
        print "Simple mouse motion"
    elif event.buttons() == QtCore.Qt.LeftButton:
        print "Left click drag"
    elif event.buttons() == QtCore.Qt.RightButton:
        print "Right click drag"
9

最简单的方法就是在 qApp 上安装一个事件过滤器:

from PyQt4 import QtGui, QtCore

class Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        widget = QtGui.QWidget(self)
        layout = QtGui.QVBoxLayout(widget)
        self.edit = QtGui.QLineEdit(self)
        self.list = QtGui.QListWidget(self)
        layout.addWidget(self.edit)
        layout.addWidget(self.list)
        self.setCentralWidget(widget)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseMove:
            if event.buttons() == QtCore.Qt.NoButton:
                pos = event.pos()
                self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
            else:
                pass # do other stuff
        return QtGui.QMainWindow.eventFilter(self, source, event)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    win = Window()
    win.show()
    app.installEventFilter(win)
    sys.exit(app.exec_())

撰写回答