使用 PyQt 快速搭建带有 GUI 的应用(5)–鼠标悬浮操作

王 茂南 2021年5月5日07:49:38
评论
4118字阅读13分43秒
摘要本文会介绍 PyQt 中鼠标悬停触发事件的做法。会通过两个例子,说明如何在鼠标悬停在不同的组件上时,触发不同的事件。

简介

在这个例子中,我们介绍两个在 PyQt 中触发事件的方式,分别是「鼠标点击」触发和「鼠标悬浮」触发。所谓「鼠标悬浮」指鼠标滑过某个区域时候来触发事件。

不像是「鼠标点击」进行触发可以使用 .clicked.connect,这里的「鼠标悬浮」我们需要对指定的组件使用 installEventFilter,接着在下面定义 eventFilter,最后根据 QEvent.EnterQEvent.Leave 来判断鼠标的进入和离开。(后面会有例子)

这里鼠标悬浮触发事件,主要参考自下面的例子,Mouseover event for a PyQT5 Label

 

简单的鼠标悬浮触发例子

首先我们看一个简单的例子,我们定义一个 QLabel 的小组件,并实现当鼠标移动在上面和离开的时候打印文字。完整的代码如下所示:

  1. from PyQt5.QtWidgets import *
  2. from PyQt5.QtGui import *
  3. from PyQt5.QtCore import *
  4. import sys
  5. class mouseoverEvent(QWidget):
  6.     def __init__(self):
  7.         super().__init__()
  8.         self.initUI()
  9.     def initUI(self):
  10.         self.lbl=QLabel(self)
  11.         self.lbl.setText("Hover over me to stop the program") # QLabel 显示的文字
  12.         self.lbl.installEventFilter(self# 对 QLabel 设置 EventFilter
  13.         self.setGeometry(1000, 30, 300, 100) # 设置 QLabel 的大小
  14.         self.show()
  15.     def eventFilter(selfobject, event):
  16.         if event.type() == QEvent.Enter: # 当鼠标进入时
  17.             print('Mouse is over the label, Object Text, {}'.format(object.text()))
  18.             return True
  19.         elif event.type() == QEvent.Leave: # 当鼠标离开时
  20.             print('Mouse is not over the label')
  21.         return False
  22. if __name__ == '__main__':
  23.     app = QApplication(sys.argv)
  24.     ex = mouseoverEvent()
  25.     sys.exit(app.exec_())

我们对上面的代码进行简单的解释:

  • 我们在 initUI 主要构建的界面相关的代码,同时对 QLabel 进行 EventFilter 的绑定;
  • 详细的 eventFilter 定义如下,当 event.typeQEvent.Enter 的时候,会触发 print 的内容,其中 object.text() 会是组件的文字内容。
  • eventFilter 中,这里的 return Truereturn False 是一定需要的。

最终的效果如下所示,鼠标进入和离开都会有内容打印出来

使用 PyQt 快速搭建带有 GUI 的应用(5)–鼠标悬浮操作

 

鼠标点击与悬浮触发例子

上面是一个比较简单的鼠标进入和离开触发 event 的例子。现在我们的需求会更加复杂一些,我们希望移动在不同的 Label 上的时候,触发不同的事件。这个我们可以通过 object.text() 的这种方式进行判断。我们看下面这个例子。

界面设计

我们使用 QtDesigner 来设计一个非常简单的界面。页面由左右两个部分组成,左侧是按钮,右侧是 stacked widget。把鼠标放在不同的按钮上,右侧会出现不同的 page

总体界面如下所示,这一部分就不放代码了,可以自己在 QtDesigner 中简单设计一下即可。

使用 PyQt 快速搭建带有 GUI 的应用(5)–鼠标悬浮操作

在这里,stacked widget 中共有 4 个page,按顺序分别是,「首页」,「第一页」,「第二页」,「第三页」。如下所示:

使用 PyQt 快速搭建带有 GUI 的应用(5)–鼠标悬浮操作

 

功能部分代码编写

上面我们完成了界面的设计,这里我们完成主要功能模块的设计。完整的代码如下所示:

  1. import os
  2. import sys
  3. from PyQt5.QtCore import QEvent
  4. from PyQt5.uic import loadUi
  5. from PyQt5.QtWidgets import QApplication, QMainWindow
  6. class HoverApp(QMainWindow):
  7.     """鼠标滑过, 触发动作
  8.     """
  9.     def __init__(self, parent=None) -> None:
  10.         super().__init__(parent)
  11.         loadUi(os.path.abspath(os.path.join(os.path.dirname(__file__), 'pp.ui')), self)
  12.         # 绑定按钮
  13.         self.pushButton.installEventFilter(self)
  14.         self.pushButton_3.installEventFilter(self)
  15.         # 鼠标移动与离开 2
  16.         self.pushButton_2.clicked.connect(self.click_switch_tab) # 点击按钮
  17.     def eventFilter(selfobject, event):
  18.         if hasattr(object, 'text'): # 确认一下 object 是否有 text 的属性
  19.             if event.type() == QEvent.Enter: # 鼠标进入
  20.                 if object.text() == '悬停显示第一页': # 判断鼠标进入哪一个 QPushButton
  21.                     self.hover_switch_tab_1(enter=True)
  22.                 elif object.text() == '悬停显示第二页':
  23.                     self.hover_switch_tab_2(enter=True)
  24.                 return True
  25.             elif event.type() == QEvent.Leave: # 鼠标离开
  26.                 if object.text() == '悬停显示第一页':
  27.                     self.hover_switch_tab_1(enter=False)
  28.                 elif object.text() == '悬停显示第二页':
  29.                     self.hover_switch_tab_2(enter=False)
  30.                 return True
  31.         return False
  32.     def hover_switch_tab_1(self, enter=False):
  33.         """悬停显示页面 1, 移走时候显示首页
  34.         """
  35.         if enter: # 进入时
  36.             print('切换到第一页')
  37.             self.stackedWidget.setCurrentIndex(1)
  38.         else:
  39.             print('切换回首页')
  40.             self.stackedWidget.setCurrentIndex(0) # 首页下标是 0
  41.     def hover_switch_tab_2(self, enter=False):
  42.         """悬停显示页面 2, 移走时候显示首页
  43.         """
  44.         if enter: # 进入时
  45.             print('切换到第二页')
  46.             self.stackedWidget.setCurrentIndex(2)
  47.         else:
  48.             print('切换回首页')
  49.             self.stackedWidget.setCurrentIndex(0) # 首页下标是 0    
  50.     def click_switch_tab(self):
  51.         """点击切换到第三页
  52.         """
  53.         print('切换到第三页.')
  54.         self.stackedWidget.setCurrentIndex(3)

主要看上面的eventFilter,根据 event.typeobject.text 来判断鼠标进入了哪一个组件,从而触发不同的效果。

切换 stackedWidget 是通过 self.stackedWidget.setCurrentIndex 来实现的,第一个 page 的 ID 是从 0 开始的。

这里还需要有一个注意的是,上面绑定按钮的时候,例如 self.pushButtonself.pushButton_3 是 组件的 object_name,这个可以从 QtDesigner 中查询到。

最终的效果如下所示,可以看到:

  • 当鼠标悬停在「悬停显示第一页」时,会显示第一页,离开则显示首页;
  • 当鼠标悬停在「悬停显示第二页」时,会显示第二页,离开则显示首页;
  • 当鼠标悬停在「点击显示第三页」时,会显示第三页
使用 PyQt 快速搭建带有 GUI 的应用(5)–鼠标悬浮操作

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2021年5月5日07:49:38
  • 转载请务必保留本文链接:https://mathpretty.com/13665.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: