【问题标题】:Pyqt Mouse MouseButtonDblClick eventPyqt 鼠标 MouseButtonDblClick 事件
【发布时间】:2015-12-14 08:17:41
【问题描述】:

我很难区分鼠标单击事件和鼠标单击事件。我创建了一个事件过滤器,但鼠标双击也给了我一个信号。在我的代码中,我必须将两个事件分开以连接到不同的功能。任何人都可以建议我如何做到这一点?

这是一个例子。我想要的是,如果发生双击鼠标,只有 MouseButtonDblClick 应该发出信号,而不是 LeftButton 和 MouseButtonDblClick:

    # coding: utf-8
    import sys

    from PyQt4 import QtCore, QtGui


    class MyDialog(QtGui.QDialog):
        def __init__(self, parent=None):
            super(MyDialog, self).__init__(parent)

            self.button1 = QtGui.QPushButton("Button 1")
            self.button2 = QtGui.QPushButton("Button 2")

            hbox = QtGui.QHBoxLayout()
            hbox.addWidget(self.button1)
            hbox.addWidget(self.button2)
            self.setLayout(hbox)

            self.button1.installEventFilter(self)

        def eventFilter(self, obj, event):

            if event.type() == QtCore.QEvent.MouseButtonPress:
                if event.button() == QtCore.Qt.LeftButton:
                    #If image is left clicked, display a red bar.
                    print 'one left'
                elif event.button() == QtCore.Qt.RightButton:
                    print 'one right'
            elif event.type() == QtCore.QEvent.MouseButtonDblClick:
                #If image is double clicked, remove bar.
                print 'two'

            return super(MyDialog, self).eventFilter(obj, event)


    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        w = MyDialog()
        w.show()
        sys.exit(app.exec_())

提前谢谢你!

斯蒂芬妮

【问题讨论】:

    标签: python pyqt mouseevent


    【解决方案1】:

    这是一种 hack,但它应该可以解决问题。 此外,我使用了新型信号而不是您的事件过滤器,您应该考虑这一点。 在这里,ClickHandler 类计算第一次点击与其计时器超时事件之间的点击次数。

    from PyQt4 import QtCore, QtGui
    
    class ClickHandler():
        def __init__(self, time):
            self.timer = QtCore.QTimer()
            self.timer.setInterval(time)
            self.timer.setSingleShot(True)
            self.timer.timeout.connect(self.timeout)
            self.click_count = 0
    
        def timeout(self):
            if self.click_count == 1:
                print('Single click')
            elif self.click_count > 1:
                print('Double click')    
            self.click_count = 0
    
        def __call__(self):
            self.click_count += 1
            if not self.timer.isActive():
                self.timer.start()
    
    
    class MyDialog(QtGui.QDialog):
        def __init__(self, parent=None):
            super(MyDialog, self).__init__(parent)
    
            self.button1 = QtGui.QPushButton("Button 1")
            hbox = QtGui.QHBoxLayout()
            hbox.addWidget(self.button1)
            self.setLayout(hbox)
    
            self.click_handler = ClickHandler(300)
            self.button1.clicked.connect(self.click_handler)
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        w = MyDialog()
        w.show()
        sys.exit(app.exec_())
    

    编辑:第二个更清洁的版本,带有处理左右点击信号的 CustomButton 类:

    from PyQt4 import QtCore, QtGui
    
    class CustomButton(QtGui.QPushButton):
    
        left_clicked= QtCore.pyqtSignal(int)
        right_clicked = QtCore.pyqtSignal(int)
    
        def __init__(self, *args, **kwargs):
            QtGui.QPushButton.__init__(self, *args, **kwargs)
            self.timer = QtCore.QTimer()
            self.timer.setInterval(250)
            self.timer.setSingleShot(True)
            self.timer.timeout.connect(self.timeout)
            self.left_click_count = self.right_click_count = 0
    
        def mousePressEvent(self, event):
            if event.button() == QtCore.Qt.LeftButton:
                self.left_click_count += 1
                if not self.timer.isActive():
                    self.timer.start()
            if event.button() == QtCore.Qt.RightButton:
                self.right_click_count += 1
                if not self.timer.isActive():
                    self.timer.start()
    
        def timeout(self):
            if self.left_click_count >= self.right_click_count:
                self.left_clicked.emit(self.left_click_count)
            else:
                self.right_clicked.emit(self.right_click_count)
            self.left_click_count = self.right_click_count = 0
    
    
    class MyDialog(QtGui.QDialog):
        def __init__(self, parent=None):
            super(MyDialog, self).__init__(parent)
            self.button1 = CustomButton("Button 1")
            hbox = QtGui.QHBoxLayout()
            hbox.addWidget(self.button1)
            self.setLayout(hbox)
            self.button1.left_clicked[int].connect(self.left_click)
            self.button1.right_clicked[int].connect(self.right_click)
    
        def left_click(self, nb):
            if nb == 1: print('Single left click')
            else: print('Double left click')
    
        def right_click(self, nb):
            if nb == 1: print('Single right click')
            else: print('Double right click')
    
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        w = MyDialog()
        w.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 谢谢你,hack 有效。我有点惊讶,因为我现在正在从 wxPython 切换到 Qt,他们会自动处理它。我不知道。也谢谢你提到新式信号,我去看看。
    • 还有一个问题,它只处理左键点击。我如何连接鼠标右键单击/双击?
    • QAbstractButton 仅对左键单击(单击、按下、释放、切换)实现信号。如果您真的想要其他信号,您可能必须创建一个继承自 QAbstractButton 或 QPushButton 的新类,以实现右键单击信号。你甚至可以将双击机制放在这个类中。因为你想要做的似乎根本不是 QPushButton 的常规用法。
    • 谢谢文森特。我想在 QLabel 的图像上使用这些事件,我想我会创建一个扩展的 QLabel 类。
    • 查看我的编辑,我编写了一个更简洁的版本,其中计时器机制直接在自定义按钮类中实现。
    【解决方案2】:

    你应该看看Double-Click-Capturing上的这个帖子。

    计时器可能会完成这项工作。但是,不相关的单击和双击可能是个坏主意(请参阅 Bill's answer 到“Qt 中的单击和双击事件之间的区别”)。

    【讨论】:

      猜你喜欢
      • 2012-03-15
      • 2011-07-25
      • 2015-10-12
      • 1970-01-01
      • 2011-04-20
      • 2011-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多