文章目录(Table of Contents)
简介
在这个例子中,我们介绍两个在 PyQt 中触发事件的方式,分别是「鼠标点击」触发和「鼠标悬浮」触发。所谓「鼠标悬浮」指鼠标滑过某个区域时候来触发事件。
不像是「鼠标点击」进行触发可以使用 .clicked.connect
,这里的「鼠标悬浮」我们需要对指定的组件使用 installEventFilter
,接着在下面定义 eventFilter
,最后根据 QEvent.Enter
和 QEvent.Leave
来判断鼠标的进入和离开。(后面会有例子)
这里鼠标悬浮触发事件,主要参考自下面的例子,Mouseover event for a PyQT5 Label。
简单的鼠标悬浮触发例子
首先我们看一个简单的例子,我们定义一个 QLabel
的小组件,并实现当鼠标移动在上面和离开的时候打印文字。完整的代码如下所示:
- from PyQt5.QtWidgets import *
- from PyQt5.QtGui import *
- from PyQt5.QtCore import *
- import sys
- class mouseoverEvent(QWidget):
- def __init__(self):
- super().__init__()
- self.initUI()
- def initUI(self):
- self.lbl=QLabel(self)
- self.lbl.setText("Hover over me to stop the program") # QLabel 显示的文字
- self.lbl.installEventFilter(self) # 对 QLabel 设置 EventFilter
- self.setGeometry(1000, 30, 300, 100) # 设置 QLabel 的大小
- self.show()
- def eventFilter(self, object, event):
- if event.type() == QEvent.Enter: # 当鼠标进入时
- print('Mouse is over the label, Object Text, {}'.format(object.text()))
- return True
- elif event.type() == QEvent.Leave: # 当鼠标离开时
- print('Mouse is not over the label')
- return False
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- ex = mouseoverEvent()
- sys.exit(app.exec_())
我们对上面的代码进行简单的解释:
- 我们在
initUI
主要构建的界面相关的代码,同时对QLabel
进行EventFilter
的绑定; - 详细的
eventFilter
定义如下,当event.type
是QEvent.Enter
的时候,会触发print
的内容,其中object.text()
会是组件的文字内容。 - 在
eventFilter
中,这里的return True
和return False
是一定需要的。
最终的效果如下所示,鼠标进入和离开都会有内容打印出来:
鼠标点击与悬浮触发例子
上面是一个比较简单的鼠标进入和离开触发 event 的例子。现在我们的需求会更加复杂一些,我们希望移动在不同的 Label 上的时候,触发不同的事件。这个我们可以通过 object.text()
的这种方式进行判断。我们看下面这个例子。
界面设计
我们使用 QtDesigner 来设计一个非常简单的界面。页面由左右两个部分组成,左侧是按钮,右侧是 stacked widget。把鼠标放在不同的按钮上,右侧会出现不同的 page。
总体界面如下所示,这一部分就不放代码了,可以自己在 QtDesigner 中简单设计一下即可。
在这里,stacked widget 中共有 4 个page,按顺序分别是,「首页」,「第一页」,「第二页」,「第三页」。如下所示:
功能部分代码编写
上面我们完成了界面的设计,这里我们完成主要功能模块的设计。完整的代码如下所示:
- import os
- import sys
- from PyQt5.QtCore import QEvent
- from PyQt5.uic import loadUi
- from PyQt5.QtWidgets import QApplication, QMainWindow
- class HoverApp(QMainWindow):
- """鼠标滑过, 触发动作
- """
- def __init__(self, parent=None) -> None:
- super().__init__(parent)
- loadUi(os.path.abspath(os.path.join(os.path.dirname(__file__), 'pp.ui')), self)
- # 绑定按钮
- self.pushButton.installEventFilter(self)
- self.pushButton_3.installEventFilter(self)
- # 鼠标移动与离开 2
- self.pushButton_2.clicked.connect(self.click_switch_tab) # 点击按钮
- def eventFilter(self, object, event):
- if hasattr(object, 'text'): # 确认一下 object 是否有 text 的属性
- if event.type() == QEvent.Enter: # 鼠标进入
- if object.text() == '悬停显示第一页': # 判断鼠标进入哪一个 QPushButton
- self.hover_switch_tab_1(enter=True)
- elif object.text() == '悬停显示第二页':
- self.hover_switch_tab_2(enter=True)
- return True
- elif event.type() == QEvent.Leave: # 鼠标离开
- if object.text() == '悬停显示第一页':
- self.hover_switch_tab_1(enter=False)
- elif object.text() == '悬停显示第二页':
- self.hover_switch_tab_2(enter=False)
- return True
- return False
- def hover_switch_tab_1(self, enter=False):
- """悬停显示页面 1, 移走时候显示首页
- """
- if enter: # 进入时
- print('切换到第一页')
- self.stackedWidget.setCurrentIndex(1)
- else:
- print('切换回首页')
- self.stackedWidget.setCurrentIndex(0) # 首页下标是 0
- def hover_switch_tab_2(self, enter=False):
- """悬停显示页面 2, 移走时候显示首页
- """
- if enter: # 进入时
- print('切换到第二页')
- self.stackedWidget.setCurrentIndex(2)
- else:
- print('切换回首页')
- self.stackedWidget.setCurrentIndex(0) # 首页下标是 0
- def click_switch_tab(self):
- """点击切换到第三页
- """
- print('切换到第三页.')
- self.stackedWidget.setCurrentIndex(3)
主要看上面的eventFilter
,根据 event.type
和 object.text
来判断鼠标进入了哪一个组件,从而触发不同的效果。
切换 stackedWidget 是通过 self.stackedWidget.setCurrentInde
x 来实现的,第一个 page 的 ID 是从 0 开始的。
这里还需要有一个注意的是,上面绑定按钮的时候,例如 self.pushButton
和 self.pushButton_3
是 组件的 object_name
,这个可以从 QtDesigner
中查询到。
最终的效果如下所示,可以看到:
- 当鼠标悬停在「悬停显示第一页」时,会显示第一页,离开则显示首页;
- 当鼠标悬停在「悬停显示第二页」时,会显示第二页,离开则显示首页;
- 当鼠标悬停在「点击显示第三页」时,会显示第三页;
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论