PyQt之按钮传递鼠标按下事件点击失效

时间:2024-02-21 08:16:22

引子:每一个桌面应用程序或多或少的使用了按钮,而使用Qt自定义按钮几乎随处可见。

问题:当在父窗口中创建按钮后,经常需要点击按钮同时响应父窗口与按钮绑定的两个操作(甚至更多)。而自定义按钮类将鼠标按下事件传递至父窗口时,往往碰到按钮点击失效的问题。

解决方案:

1.根据需求自定义按钮类(以QToolButton为例)

 1 class MyButton(QtGui.QToolButton):
2 \'\'\'自定义按钮类\'\'\'
3 ############################## 构造、析构函数 ##################################
4 def __init__(self,parent=None):
5 \'\'\'构造函数\'\'\'
6 # 调用父类构造函数
7 super(MyButton,self).__init__(parent)
8 # 设置按钮尺寸
9 self.setFixedSize(QtCore.QSize(800,120))
10 # 设置按钮背景颜色
11 self.setStyleSheet(\'\'\'background-color:red;\'\'\')
12 ################################ 事件 #########################################
13 def mousePressEvent(self,event):
14 \'\'\'鼠标按下事件\'\'\'
15 # 判断是否为鼠标左键按下
16 if event.button() == QtCore.Qt.LeftButton:
17 # 传递至父窗口响应鼠标按下事件
18 self.parent().mousePressEvent(event)


2.在主窗口中添加按钮,点击按钮先弹出对话框,然后设置主窗口背景颜色

 1 class MyWindow(QtGui.QWidget):
2 \'\'\'自定义窗口类\'\'\'
3 ############################# 构造、析构函数 #################################
4 def __init__(self,parent=None):
5 \'\'\'构造函数\'\'\'
6 # 调用父类构造函数
7 super(MyWindow,self).__init__(parent)
8 # 设置窗口固定尺寸
9 self.setFixedSize(QtCore.QSize(800,600))
10 # 创建主控件
11 bodyWidget = QtGui.QWidget(self)
12 # 创建主布局
13 mainLayout = QtGui.QVBoxLayout(bodyWidget)
14 # 遍历创建按钮
15 for i in range(4):
16 # 创建自定义按钮
17 button = MyButton(self)
18 # 设置文本内容
19 button.setText("测试%s" % i)
20 # 添加控件
21 mainLayout.addWidget(button)
22 # 设置按钮点击连接槽函数
23 button.clicked.connect(self.OnClick)
24 ############################### 命令 ########################################
25 def OnClick(self):
26 \'\'\'响应点击\'\'\'
27 QtGui.QMessageBox.about(self,"测试","点击弹出窗口成功")
28 ################################ 事件 ########################################
29 def mousePressEvent(self,event):
30 \'\'\'鼠标按下事件\'\'\'
31 # 判断是否为鼠标左键按下
32 if event.button() == QtCore.Qt.LeftButton:
33 # 设置窗口背景颜色
34 self.setStyleSheet(\'\'\'background-color:cyan;\'\'\')

实际运行效果并没用弹出对话框,因为按钮点击失效

3.解决办法:在自定义按钮类的鼠标按下事件函数中,当判断为鼠标左键按下后,发送按钮发送点击信号

1 def mousePressEvent(self,event):
2 \'\'\'鼠标按下事件\'\'\'
3 # 判断是否为鼠标左键按下
4 if event.button() == QtCore.Qt.LeftButton:
5   # 发射点击信号
6 self.clicked.emit(True)
7 # 传递至父窗口响应鼠标按下事件
8 self.parent().mousePressEvent(event)

运行效果如下:


4.完整示例代码:

 1 # coding=gbk
2
3 # 导入模块
4 import sys
5 from PyQt4 import QtGui,QtCore
6
7 ################################# 自定义窗口类 #####################################
8 class MyWindow(QtGui.QWidget):
9 \'\'\'自定义窗口类\'\'\'
10 ############################# 构造、析构函数 #################################
11 def __init__(self,parent=None):
12 \'\'\'构造函数\'\'\'
13 # 调用父类构造函数
14 super(MyWindow,self).__init__(parent)
15 # 设置窗口固定尺寸
16 self.setFixedSize(QtCore.QSize(800,600))
17 # 创建主控件
18 bodyWidget = QtGui.QWidget(self)
19 # 创建主布局
20 mainLayout = QtGui.QVBoxLayout(bodyWidget)
21 # 遍历创建按钮
22 for i in range(4):
23 # 创建自定义按钮
24 button = MyButton(self)
25 # 设置文本内容
26 button.setText("测试%s" % i)
27 # 添加控件
28 mainLayout.addWidget(button)
29 # 设置按钮点击连接槽函数
30 button.clicked.connect(self.OnClick)
31 ############################### 命令 ########################################
32 def OnClick(self):
33 \'\'\'响应点击\'\'\'
34 QtGui.QMessageBox.about(self,"测试","点击弹出窗口成功")
35 ################################ 事件 ########################################
36 def mousePressEvent(self,event):
37 \'\'\'鼠标按下事件\'\'\'
38 # 判断是否为鼠标左键按下
39 if event.button() == QtCore.Qt.LeftButton:
40 # 设置窗口背景颜色
41 self.setStyleSheet(\'\'\'background-color:cyan;\'\'\')
42
43 ################################## 自定义按钮类 ####################################
44 class MyButton(QtGui.QToolButton):
45 \'\'\'自定义按钮类\'\'\'
46 ############################## 构造、析构函数 ##################################
47 def __init__(self,parent=None):
48 \'\'\'构造函数\'\'\'
49 # 调用父类构造函数
50 super(MyButton,self).__init__(parent)
51 # 设置按钮尺寸
52 self.setFixedSize(QtCore.QSize(800,120))
53 # 设置按钮背景颜色
54 self.setStyleSheet(\'\'\'background-color:red;\'\'\')
55 ################################ 事件 #########################################
56 def mousePressEvent(self,event):
57 \'\'\'鼠标按下事件\'\'\'
58 # 判断是否为鼠标左键按下
59 if event.button() == QtCore.Qt.LeftButton:
60 # 发射点击信号
61 self.clicked.emit(True)
62 # 传递至父窗口响应鼠标按下事件
63 self.parent().mousePressEvent(event)
64
65 ################################## 主函数 ##########################################
66 if __name__ == "__main__":
67 \'\'\'主函数\'\'\'
68 # 声明变量
69 app = QtGui.QApplication(sys.argv)
70 # 创建窗口
71 window = MyWindow()
72 # 设置窗口显示
73 window.show()
74 #应用程序事件循环
75 sys.exit(app.exec_())