司开星的博客

PyQt4 中区分 QListWidget 的双击(itemDoubleClicked)和单击(itemClicked) 信号

问题来源

QListWidget 中有itemClicked和itemDoubleClicked两个信号, 分别代表鼠标单击和鼠标双击信号. 不过如果要同时用这两个信号就会发现itemDoubleClicked 信号会触发itemClicked信号. 如果是两个无关的操作倒是没关系, 但如果正好要把这两个信号的槽定义为有关联的动作就要区分这两个信号了, 也就是让itemDoubleClicked不会触发itemClicked.

解决方法

Qt 中对于这个问题没有现成的解决方法. 有些人建议如果能不同时使用这两个信号就不同时使用. 如果实在想用也是有办法解决的, 自己写个区分两个信号的方法即可.

在Stackoverflow上有这样一种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void YourClass::itemClicked(QListWidgetItem* listWidgetItem) {
if (!mDoubleClicked) {
QTimer::singleShot(300, this, SLOT(itemClickedTimeout()));
mSingleClickedItem = listWidgetItem;
}
}

void YourClass::itemClickedTimeout() {
if (!mDoubleClicked) {
// do something, listitem has been clicked once
} else mDoubleClicked = false;
}

void YourClass::itemDoubleClicked(QListWidgetItem* listWidgetItem) {
mDoubleClicked = true;

// do something, listitem has been clicked twice
}

转换成PyQt的写法就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Main(QtGui.QMainWindow):

def __init__():

self.is_double_clicked = False
self.listwidget.itemClicked.connect(self.item_clicked)
self.listwidget.itemDoubleClicked.connect(self.item_double_clicked)

.....................................

def item_clicked(self, item):
if not self.is_double_clicked:
QtCore.QTimer.singleShot(300, self.item_clicked_timeout)

def item_clicked_timeout(self):
if not self.is_double_clicked:
# do something when item clicked
pass
else:
self.is_double_clicked = False

def item_double_clicked(self):
self.is_double_clicked = True
# do something when item double clicked
pass

参考资料:

QListWidget itemClicked and itemDoubleClicked - block single click if double click