Reputation: 2520
I have some trouble to distinguish between a single and a double mouse click event. I have created an event filter but a mouse double click also gives me a single signal back. In my code I have to separate both events to connect to different functions. Can anybody suggest me how to do this?
Here is an example. What I want is, if a double mouse click happen, only the MouseButtonDblClick should give a signal and not the LeftButton and 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_())
Thank you in advance!
Stefanie
Upvotes: 2
Views: 16023
Reputation: 13415
It's kind of a hack, but it should do the trick. Also, I used new-style signals instead of your event filter, something you should consider. Here, the ClickHandler class counts the number of clicks between the first click and the timeout event of its timer.
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_())
EDIT : A second cleaner version with a CustomButton class that handles left and right click signals:
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_())
Upvotes: 5
Reputation: 5336
You should have a look at this thread on Double-Click-Capturing.
A Timer might do the job. However, it is probably a bad idea to have unrelated single clicks and double clicks (see Bill's answer to "Distinguish between single and double click events in Qt").
Upvotes: 2