28. 事件处理

news/2025/1/16 18:36:03/文章来源:https://www.cnblogs.com/FlurryHeart/p/18675576

一、事件与事件处理

1.1、什么是事件

  事件是程序收到外界的输入,处于某种状态时自动发送的信号。事件有固定的类型,每种类型有自己的处理函数,用户只要重写这些函数,即可达到特定的目的。通过事件可以用一个控件监测另外一个控件,并可过滤被监测控件发出的事件。

  可视化应用程序在接受外界输入设备的输入时,会对输入设备输入的信息进行分类,根据分类的不同,用不同的函数进行处理,做出不同的反应。外界对 PySide6 程序进行输入信息的过程称为 事件。PySide6 程序对外界的输入进行处理的过程称为 事件处理,根据外界输入信息的不同,处理事件的函数也不同。

  在主程序中都会创建一个 QApplication 的应用程序实例对象,然后调用实例对象的 exec() 函数,这将使应用程序进入一个循环,不断监听外界输入的信息。当输入的信息满足某种分类时,将会产生一个事件对象 QEvent(),事件对象中记录了外界输入的信息,并将事件对象发送给处理该事件对象的函数进行处理。

  事件与槽相似,但是又有不同。信号 是指控件或窗口本身满足一定条件时,发送一个带数据的信息或不带数据的信息,需要编程人员为这个信息单独写处理这个信息的槽函数,并将信号和槽函数关联,发送信号时,自动执行与之关联的槽函数。而 事件 是外界对程序的输入,将外界的输入进行分类后交给函数处理,处理事件的函数是固定的,只需要编程人员把处理事件的函数重写,来达到处理外界输入的目的,而不需要将事件与处理事件的函数进行连接,系统会自动调用能处理事件的函数,并把相关数据作为实参传递给处理事件的函数。

  我们可以在终端中使用 pip 安装 pyside6 模块。

pip install pyside6

1.2、QEvent类

  QEvent 类是所有事件的基类,它在 QtCore 模块中。外界输入给程序的信息首先交给 QEvent 进行分类,得到不同类型的事件,然后系统将事件及相关信息交给控件或窗口的事件处理函数进行处理,得到对外界输入的响应。

  QEvent 类的属性只有 accepted,常用的方法如下:

# 实例方法
accept() -> None                        # 事件被接受
ignore() -> None                        # 事件被拒绝
isAccepted() -> bool                    # 事件是否被接受
setAccepted(accepted:bool) -> None      # 设置事件是否被接受
clone() -> QEvent                       # 重写该函数,返回事件的副本
isPointerEvent() -> bool                # 获取事件是否为QPointerEvent事件
isSinglePointEvent() -> bool            # 获取事件是否为QSinglePointEvent事件
spontaneous() -> bool                   # 获取事件是否立即被处理
type() -> QEvent.Type                   # 获取事件的类型# 静态方法
registerEventType(hint:int=-1) -> int   # 注册新的事件类型

  用 accept()setAccepted(True) 方法接受一个事件,用 ignore()setAccepted(False) 方法拒绝一个事件。被接受的事件不会再传递给其他对象;被拒绝的事件会传递给其他对象处理,如果没有对象处理,则该事件会被丢弃。如果事件被 QWidget 的 event() 函数进行了处理,则用 spontaneous() 方法的返回值是 True,否则返回值是 False。event() 函数根据事件类型起到分发事件到指定处理函数的作用,可以在 event() 函数中对事件进行处理。用 type() 方法可以返回事件的类型。QEvent 中定义了事件的类型。

QEvent定义的主要事件类型

1.3、event()函数

  当 GUI 应用程序捕捉到事件发生后,会首先将其发送到 QWidget 或子类的 event(QEvent) 函数中进行数据处理,如果没有重写 event() 函数进行事件处理,事件将会分发到事件默认的处理函数中,因此 event() 函数是事件的集散地。如果重写了 event() 函数,当 event() 函数的返回值是 True 时,表示事件已经处理完毕,事件不会再发送给其他处理函数;当 event() 函数的返回值是 False 时,表示事件还没有处理完毕。event() 函数可以截获某些类型的事件,并处理事件。

二、鼠标事件和滚轮事件

2.1、鼠标事件

  鼠标事件类 QMouseEvent 涉及鼠标按键的单击、释放和鼠标移动操作,与 QMouseEvent 关联的事件类型有 QEvent.MouseButtonDblClickQEvent.MouseButtonPressQEvent.MouseButtonReleaseQEvent.MouseMove

  当在一个窗口或控件中按住鼠标按键或释放按键时会产生鼠标事件 QMouseEvent,鼠标移动事件只会在按下鼠标按键的情况下才会发生,除非通过显式调用窗口的 setMouseTracking(True) 函数来开启鼠标轨迹跟踪,这种情况下只要鼠标指针移动,就会产生一系列鼠标事件。

  当产生鼠标事件时,会生成 QMouseEvent 类的实例对象,并将实例对象作为实参传递给相关的处理函数。QMouseEvent 类包含了用于描述鼠标事件的参数。QMouseEvent 类在 QtGui 模块中,它的常用方法如表下所示。

button() -> Qt.MouseButton                  # 获取产生鼠标事件的按键
buttons() -> Qt.MouseButtons                # 获取产生鼠标事件是被按下的按键modifiers() -> Qt.KeyboardModifiers         # 获取鼠标事件的修饰键
device() -> QInputDevice                    # 获取产生鼠标事件的设备
deviceType() -> QInputDevice.deviceType     # 获取产生鼠标事件的设备类型flags() -> Qt.MouseEventFlags               # 获取鼠标事件的标识
source() -> Qt.MouseEventSource             # 获取产生鼠标事件的源globalPosition() -> QPoint                  # 获取全局的鼠标位置  
scenePosition() -> QPointF                  # 获取屏幕的鼠标位置
position() -> QPointF                       # 获取相对于控件的鼠标位置 

  用 button() 方法可以获取产生鼠标事件的按键,用 buttons() 方法获取产生鼠标事件时被按住的按键,返回值可以取值如下:

Qt.MouseButton.NoButton
Qt.MouseButton.AllButtons
Qt.MouseButton.LeftButton
Qt.MouseButton.RightButton
Qt.MouseButton.MidButton
Qt.MouseButton.MiddleButton
Qt.MouseButton.BackButton
Qt.MouseButton.ForwardButton
Qt.MouseButton.TaskButton
Qt.MouseButton.ExtraButtoni(i=1,2,…,24)

  用 source() 方法可以获取鼠标事件的来源,返回值可以取值如下:

Qt.MouseEventSource.MouseEventNotSynthesized               # 来自鼠标
Qt.MouseEventSource.MouseEventSynthesizedBySystem          # 来自鼠标和触摸屏
Qt.MouseEventSource.MouseEventSynthesizedByQt              # 来自触摸屏
Qt.MouseEventSource.MouseEventSynthesizedByApplication     # 来自应用程序

  产生鼠标事件的同时,有可能按下了键盘上的 Ctrl、Shift 或 Alt 等修饰键,用 modifiers() 方法可以获取这些键。 modifiers() 方法的返回值可以取值如下:

Qt.KeyboardModifier.NoModifier            # 没有修饰键
Qt.KeyboardModifier.ShiftModifier         # Shift键
Qt.KeyboardModifier.ControlModifier       # Ctrl键
Qt.KeyboardModifier.AltModifier           # Alt键
Qt.KeyboardModifier.MetaModifier          # Meta键,Windows系统为window键
Qt.KeyboardModifier.KeypadModifier        # 小键盘上的键
Qt.KeyboardModifier.GroupSwitchModifier   # Mode_switch键

  用 deviceType() 方法可以获取产生鼠标事件的设备类型,返回值是 QInputDevice.DeviceType 的枚举值,可取值如下:

QInputDevice.DeviceType.Unknown
QInputDevice.DeviceType.Mouse
QInputDevice.DeviceType.TouchScreen
QInputDevice.DeviceType.TouchPad
QInputDevice.DeviceType.Stylus
QInputDevice.DeviceType.Airbrush
QInputDevice.DeviceType.Puck
QInputDevice.DeviceType.Keyboard
QInputDevice.DeviceType.AllDevices

  处理 QMouseEvent 类鼠标事件的函数如下:

mouseDoubleClickEvent(event:QMouseEvent)  # 双击鼠标按键
mouseMoveEvent(event:QMouseEvent)         # 移动鼠标
mousePressEvent(event:QMouseEvent)        # 按下鼠标按键
mouseReleaseEvent(event:QMouseEvent)      # 释放鼠标按键
import sysfrom PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QFileDialog
from PySide6.QtGui import QPixmap, QPainter
from PySide6.QtCore import QRect, QPoint, Qtclass MyWidget(QWidget):def __init__(self):# 1.调用父类Qwidget类的__init__()方法super().__init__()# 2.设置鼠标单击时光标位置self.start = QPoint(0, 0)# 3.记录窗口的中心点self.center = QPoint(self.width() // 2, self.height() // 2)# 4.调用setupUi()方法初始化页面self.setup_ui()def setup_ui(self):# 1.设置窗口对象大小self.resize(700, 500)# 2.创建QPixmap图像self.pixmap = QPixmap()# 3.设置初始的宽度和高度self.pixmap_width = 0self.pixmap_height = 0# 4.设置初始的偏移量self.translate_x = 0self.translate_y = 0def mouseDoubleClickEvent(self, event):"""双击鼠标事件的处理函数"""# 1.创建文件对话框fileDialog = QFileDialog(self)# 2.设置文件过滤器fileDialog.setNameFilter("图像文件(*.png *.jpeg *.jpg *.ico)")# 3.设置文件模式fileDialog.setFileMode(QFileDialog.FileMode.ExistingFiles)# 4.判断是否选择了文件if fileDialog.exec():# 5.加载图片self.pixmap.load(fileDialog.selectedFiles()[0])# 6.获取图像的宽和高self.pixmap_width = self.pixmap.width()self.pixmap_height = self.pixmap.height()# 7.设置中心点的位置self.center = QPoint(self.width() // 2, self.height() // 2)# 8.更新窗口self.update()def mousePressEvent(self, event):"""鼠标按下事件处理函数"""# 1.获取鼠标位置self.start = event.position()def mouseMoveEvent(self, event):"""鼠标移动事件的处理的函数"""# 1.如果是按Ctrl+鼠标左键移动的话if event.modifiers() == Qt.KeyboardModifier.ControlModifier and event.buttons() == Qt.MouseButton.LeftButton:# 2.鼠标的偏移量self.translate_x = event.position().x() - self.start.x()self.translate_y = event.position().y() - self.start.y()self.start = event.position()self.update()def paintEvent(self, event):"""窗口绘制处理函数,当窗口刷新时调用该函数"""# 1.获取中心点self.center = QPoint(self.center.x() + self.translate_x, self.center.y() + self.translate_y)# 2.绘制区域的左上角点point_left_top = QPoint(self.center.x() - self.pixmap_width / 2, self.center.y() - self.pixmap_height / 2 )# 3.绘制区域的右下角点point_right_bottom = QPoint(self.center.x() + self.pixmap_width / 2, self.center.y() + self.pixmap_height / 2)# 4.图像绘制区域self.rect = QRect(point_left_top, point_right_bottom)# 5.绘图painter = QPainter(self)painter.drawPixmap(self.rect, self.pixmap)if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建一个窗口window = MyWidget()# 3.展示窗口window.show()# 4.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

2.2、滚轮事件

  鼠标滚轮的滚动事件类是 QWheelEvent,其常用方法如下:

button() -> Qt.MouseButton                  # 获取产生鼠标事件的按键
buttons() -> Qt.MouseButtons                # 获取产生鼠标事件是被按下的按键modifiers() -> Qt.KeyboardModifiers         # 获取鼠标事件的修饰键
device() -> QInputDevice                    # 获取产生鼠标事件的设备
deviceType() -> QInputDevice.deviceType     # 获取产生鼠标事件的设备类型globalPosition() -> QPoint                  # 获取全局的鼠标位置  
scenePosition() -> QPointF                  # 获取屏幕的鼠标位置
position() -> QPointF                       # 获取相对于控件的鼠标位置angleDelta() -> QPoint                      # 获取鼠标事件的旋转角度
pixelDelta() -> QPoint                      # 获取鼠标事件的移动距离
phase() -> Qt.ScrollPhase                   # 获取鼠标事件的相位
inverted() -> bool                          # 获取鼠标事件是否是反向的
source() -> Qt.MouseEventSource             # 获取产生鼠标事件的源

  angleDelta().y() 返回两次事件之间鼠标竖直滚轮旋转的角度,angleDelta().x() 返回两次事件之间鼠标水平滚轮旋转的角度。如果没有水平滚轮,则 angleDetal().x() 的值为 0,正数值表示滚轮相对于用户在向前滑动,负数值表示滚轮相对于用户在向后滑动。

  inverted() 方法将 angleDelta()pixelDelta() 的值与滚轮转向之间的取值关系反向,即正数值表示滑轮相对于用户在向后滑动,负数值表示滑轮相对于用户在向前滑动。

  phase() 方法返回设备的状态,返回值如下:

Qt.ScrollPhase.NoScrollPhase     # 不支持滚动
Qt.ScrollPhase.ScrollBegin       # 开始位置
Qt.ScrollPhase.ScrollUpdate      # 处于滚动状态
Qt.ScrollPhase.ScrollEnd         # 结束位置
Qt.ScrollPhase.ScrollMomentum    # 不触碰设备,由于惯性仍处于滚动状态

  处理 QWheelEvent 滚轮事件的函数如下:

wheelEvent(event:QWheelEvent)
import sysfrom PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QFileDialog
from PySide6.QtGui import QPixmap, QPainter
from PySide6.QtCore import QRect, QPoint, Qtclass MyWidget(QWidget):def __init__(self):# 1.调用父类Qwidget类的__init__()方法super().__init__()# 2.设置鼠标单击时光标位置self.start = QPoint(0, 0)# 3.记录窗口的中心点self.center = QPoint(self.width() // 2, self.height() // 2)# 4.调用setupUi()方法初始化页面self.setup_ui()def setup_ui(self):# 1.设置窗口对象大小self.resize(700, 500)# 2.创建QPixmap图像self.pixmap = QPixmap()# 3.设置初始的宽度和高度self.pixmap_width = 0self.pixmap_height = 0# 4.设置初始的偏移量self.translate_x = 0self.translate_y = 0# 5.设置缩放比例self.pixmap_scale_x = 0self.pixmap_scale_y = 0def mouseDoubleClickEvent(self, event):"""双击鼠标事件的处理函数"""# 1.创建文件对话框fileDialog = QFileDialog(self)# 2.设置文件过滤器fileDialog.setNameFilter("图像文件(*.png *.jpeg *.jpg *.ico)")# 3.设置文件模式fileDialog.setFileMode(QFileDialog.FileMode.ExistingFiles)# 4.判断是否选择了文件if fileDialog.exec():# 5.加载图片self.pixmap.load(fileDialog.selectedFiles()[0])# 6.获取图像的宽和高self.pixmap_width = self.pixmap.width()self.pixmap_height = self.pixmap.height()# 7.设置中心点的位置self.center = QPoint(self.width() // 2, self.height() // 2)# 8.设置缩放尺寸self.pixmap_scale_x = self.pixmap_width / (self.pixmap_width + self.pixmap_height)self.pixmap_scale_y = self.pixmap_height / (self.pixmap_width + self.pixmap_height)# 9.更新窗口self.update()def wheelEvent(self, event):"""鼠标滚轮事件的处理函数"""# 1.如果是Ctrl键if event.modifiers() == Qt.KeyboardModifier.ControlModifier:if (self.pixmap_width > 10 and self.pixmap_height > 10) or event.angleDelta().y() > 0:# 2.获取缩放后的尺寸self.pixmap_width = self.pixmap_width + int(event.angleDelta().y() / 10 * self.pixmap_scale_x)self.pixmap_height = self.pixmap_height + int(event.angleDelta().y() / 10 * self.pixmap_scale_y)# 3.更新画面self.update()print(self.pixmap_width, self.pixmap_height)def paintEvent(self, event):"""窗口绘制处理函数,当窗口刷新时调用该函数"""# 1.获取中心点self.center = QPoint(self.center.x() + self.translate_x, self.center.y() + self.translate_y)# 2.绘制区域的左上角点point_left_top = QPoint(self.center.x() - self.pixmap_width / 2, self.center.y() - self.pixmap_height / 2 )# 3.绘制区域的右下角点point_right_bottom = QPoint(self.center.x() + self.pixmap_width / 2, self.center.y() + self.pixmap_height / 2)# 4.图像绘制区域self.rect = QRect(point_left_top, point_right_bottom)# 5.绘图painter = QPainter(self)painter.drawPixmap(self.rect, self.pixmap)if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建一个窗口window = MyWidget()# 3.展示窗口window.show()# 4.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

三、键盘事件

  键盘事件 QKeyEvent 涉及键盘键的按下和释放,与 QKeyEvent 关联的事件类型有 QEvent.KeyPressQEvent.KeyReleaseQEvent.ShortcutOverride,处理键盘事件的函数是 keyPressEvent(QKeyEvent)keyReleaseEvent(QKeyEvent)。当发生键盘事件时,将创建 QKeyEvent 的实例对象,并将实例对象作为实参传递给处理函数。

  键盘事件 QKeyEvent 的常用方法如下:

count() -> int                                      # 获取按键的数量
isAutoRepeat() -> bool                              # 获取是否是重复事件
key() -> int                                        # 获取按键的代码
matches(key:QKeySequence.StandardKey) -> bool       # 如果按键匹配标准的按键
modifiers() -> Qt.KeyboardModifiers                 # 返回按键上的字符
text() -> str                                       # 返回按键的文本

  如果按下一个键不放,将连续触发键盘事件,用 isAutoRepeat() 方法可以获取某个事件是否是重复事件。用 key() 方法可以获取按键的 Qt.key 代码值,不区分大小写;可以用 text() 方法获取按键的字符,区分大小写。用 matches(QKeySequence.StandardKey) 方法可以判断按下的键是否匹配标准的按键,QKeySequence.StandardKey 中定义了常规的标准按键,例如 Ctrl+C 表示复制、Ctrl+V 表示粘贴、Ctrl+S 表示保存、Ctrl+O 表示打开、Ctrl+W 或 Ctrl+F4 表示关闭。

import sysfrom PySide6.QtWidgets import QApplication, QWidgetclass MyWidget(QWidget):def keyPressEvent(self, event):print(f"按键【{event.text()}】按下了")def keyReleaseEvent(self, event):print(f"按键【{event.text()}】释放了")if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建一个窗口window = MyWidget()# 3.展示窗口window.show()# 4.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

四、拖放事件

4.1、鼠标拖放事件

  拖放事件包括 鼠标进入鼠标移动鼠标释放鼠标移出 事件,对应的事件类型分别是 QEvent.DragEnter、QEvent.DragMove、QEvent.Drop 和 QEvent.DragLeave。拖放事件类分别为 QDragEnterEvent、QDragMoveEvent、QDropEvent 和 QDragLeaveEvent,其实例对象中保存着拖放信息。

  QDragEnterEvent 类是从 QDropEvent 类和 QDragMoveEvent 类继承而来的,它没有自己特有的方法;QDragMoveEvent 类是从 QDropEvent 类继承而来的,它继承了 QDropEvent 类的方法;又添加了自己新的方法;QDragLeaveEvent 类是从 QEvent 类继承而来的,它也没有自己特有的方法。

  QDropEvent 类常用的方法如下:

keyboardModifiers() -> Qt.keyboardModifiers             # 获取修饰键
mimeData() -> QMimeData                                 # 获取mime数据
mouseButtons() -> Qt.MouseButtons                       # 获取按下的鼠标按键
position() -> QPointF                                   # 获取鼠标位置
dropAction() -> Qt.DropAction                           # 获取采取的动作
possibleActions() -> Qt.DropActions                     # 获取可能的动作
proposedAction() -> Qt.DropActions                      # 系统推荐的动作
acceptProposedAction() -> None                          # 接受推荐的动作
setDropAction(action:Qt.DropAction) -> None             # 设置释放动作
source() -> QObject                                     # 获取被拖对象

  要使一个控件或窗口接受拖放,必须用 setAcceptDrops(True) 方法设置成接受拖放,在进入事件的处理函数 dragEnterEvent(QDragEnterEvent) 中,需要把事件对象设置成 accept() ,否则无法接受后续的移动和释放事件。

  拖放事件中,用 mimeData() 方法获取被拖放物体的 QMimeData 数据,MIME(multipurpose internet mail extensions) 是多用途互联网邮件扩展类型。

  在释放动作中,被拖拽的物体可以从原控件中被复制或移动到目标控件中,复制或移动动作可以通过 setDropAction(Qt.DropAction) 方法来设置,其中 Qt.DropAction 可以取值如下:

Qt.CopyAction          # 复制
Qt.MoveAction          # 移动
Qt.LinkAction          # 链接
Qt.IgnoreAction        # 什么都不做
Qt.TargetMoveAction    # 目标对象接管

  QDragMoveEvent 类常用方法如下:

accept() -> None            # 在控件或窗口的边界内都可接受移动事件
accept(r:QRect) -> None     # 在指定的区域内接受移动事件
answerRect() -> QRect       # 返回可以释放的区域
ignore() -> None            # 在整个边界内部忽略移动事件  
ignore(r:QRect) -> None     # 在指定的区域内忽略移动事件

  拖放事件的处理函数分别如下:

dragEnterEvent(event:QDragEnterEvent)
dragMoveEvent(event:QDragMoveEvent)
dropEvent(event:QDropEvent)
dragLeaveEvent(event:QDragLeaveEvent)

4.2、粘贴板数据

  QMimeData 类用于描述存放到粘贴板上的数据,并通过拖放事件传递粘贴板上的数据,从而在不同的程序间传递数据,也可以在同一个程序内传递数据。创建 QMimeData 实例对象的方法如下,它在 QtCore 模块中。

QMimeData()

  QMimeData 可以存储的数据有文本、图像、颜色和地址等。它的常用方法如下:

formats() -> List[str]                              # 获取格式列表
hasFormat(mimetype:str) -> bool                     # 获取是否有某种格式
removeFormat(mimetype:str) -> None                  # 移除格式setColorData(color:Any) -> None                     # 设置颜色数据
hasColor() -> bool                                  # 获取是否有颜色数据
colorData() -> Any                                  # 获取颜色数据setHtml(html:str) -> None                           # 设置HTML数据
hasHtml() -> bool                                   # 获取是否有HTML数据
html() -> str                                       # 获取HTML数据setImageData(image:Any) -> None                     # 设置图片数据
hasImage() -> bool                                  # 获取是否有图片数据
imageData() -> Any                                  # 获取图片数据setText(text:str) -> None                           # 设置文本数据
hasText() -> bool                                   # 获取是否有文本数据
text() -> str                                       # 获取文本数据setUrls(urls:Sequence[QUrl]) -> None                # 设置URL数据
hasUrls() -> bool                                   # 获取是否有URL数据
urls() -> List[QUrl]                                # 获取URL数据setData(mimetype:str, data:QByteArray) -> None      # 设置某种格式的数据
data(mimetype:str) -> QByteArray                    # 获取某种格式的数据clear() -> None                                     # 清空格式和数据
import sysfrom PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtGui import QPixmap, QPainter
from PySide6.QtCore import QPoint, QRectclass MyWidget(QWidget):def __init__(self):# 1.调用父类Qwidget类的__init__()方法super().__init__()# 2.设置鼠标单击时光标位置self.start = QPoint(0, 0)# 3.记录窗口的中心点self.center = QPoint(self.width() // 2, self.height() // 2)# 4.设置成接受拖放事件self.setAcceptDrops(True)# 5.调用setupUi()方法初始化页面self.setup_ui()def setup_ui(self):# 1.设置窗口对象大小self.resize(700, 500)# 2.创建QPixmap图像self.pixmap = QPixmap()# 3.设置初始的宽度和高度self.pixmap_width = 0self.pixmap_height = 0# 4.设置初始的偏移量self.translate_x = 0self.translate_y = 0def dragEnterEvent(self, event):"""拖动进入事件"""# 如果粘贴板数据是文件地址if event.mimeData().hasUrls():# 接受可移动事件event.accept()else:# 忽略可移动事件event.ignore()def dropEvent(self, event):"""释放事件"""# 1.获取被拖放图像的地址列表image_urls = event.mimeData().urls()# 2.获取被拖放文件的地址列表filename = image_urls[0].toLocalFile()# 3.加载图片self.pixmap.load(filename)# 4.获取图片的宽高self.pixmap_width = int(self.pixmap.width())self.pixmap_height = int(self.pixmap.height())# 5.设置中心点的位置self.center = QPoint(self.width() // 2, self.height() // 2)# 6.更新窗口self.update()def paintEvent(self, event):"""窗口绘制处理函数,当窗口刷新时调用该函数"""# 1.获取中心点self.center = QPoint(self.center.x() + self.translate_x, self.center.y() + self.translate_y)# 2.绘制区域的左上角点point_left_top = QPoint(self.center.x() - self.pixmap_width / 2, self.center.y() - self.pixmap_height / 2)# 3.绘制区域的右下角点point_right_bottom = QPoint(self.center.x() + self.pixmap_width / 2, self.center.y() + self.pixmap_height / 2)# 4.图像绘制区域self.rect = QRect(point_left_top, point_right_bottom)# 5.绘图painter = QPainter(self)painter.drawPixmap(self.rect, self.pixmap)if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建一个窗口window = MyWidget()# 3.展示窗口window.show()# 4.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

4.3、拖拽类

  如果要在程序内部拖放控件,需要先把控件定义成可移动控件,可移动控件需要在其内部定义 QDrag 的实例对象。QDrag 类用于拖放物体,它继承自 QObject 类,创建 QDrag 实例对象的方法如下:

QDrag(parent:QObject)

  QDrag 类常用的方法如下:

# 实例方法
exec(supportedActions:Qt.DropActions=Qt.MoveAction) -> Qt.DropAction                    # 开始拖放操作,并返回释放时的动作
exec(supportedActions:Qt.DropActions, defaultAction:Qt.DropAction) -> Qt.DropAction     # 开始拖放操作,并返回释放时的动作
defaultAction() -> Qt.DropAction                                                        # 返回默认的释放动作
setDragCursor(cursor:QPixmap, action:Qt.DropAction) -> None                             # 设置拖拽时的光标形状
dragCursor(action:Qt.DropAction) -> QPixmap                                             # 获取拖拽时的光标形状
setHotSpot(hotspot:QPoint) -> None                                                      # 设置热点位置
hotSpot() -> QPoint                                                                     # 获取热点位置
setMimeData(data:QMimeData) -> None                                                     # 设置拖放中传递的数据
mimeData() -> QMimeData                                                                 # 获取数据
setPixmap(arg__1:QPixmap) -> None                                                       # 设置拖拽式鼠标显示的图像
pixmap() -> QPixmap                                                                     # 获取图像
source() -> QObject                                                                     # 返回被拖放物体的父控件
target() -> QObject                                                                     # 返回目标控件
supportedActions() -> Qt.DropActions                                                    # 获取支持的动作# 静态方法
cancel() -> None                                                                        # 取消拖放

  创建 QDrag 实例对象后,用 exec(supportedActions:Qt.DropActions,defaultAction:Qt.DropAction)exec(supportedActions:Qt.DropActions=Qt.MoveAction) 方法开启拖放,参数是拖放事件支持的动作和默认动作, Qt.DropAction 可以取值如下:

Qt.DropAction.CopyAction           # 复制数据到目标对象
Qt.DropAction.MoveAction           # 移动数据到目标对象
Qt.DropAction.LinkAction           # 在目标和原对象之间建立链接关系
Qt.DropAction.IgnoreAction         # 忽略,对数据不做任何事情
Qt.DropAction.TargetMoveAction     # 目标对象接管数据

  用 setHotSpot(QPoint) 方法设置热点位置。热点位置是拖拽过程中,光标相对于控件左上角的位置。为了防止误操作,可以用 QApplication 的 setStartDragDistance(int) 方法和 setStartDragTime(msec) 方法设置拖动开始一定距离或一段时间后才开始进行拖放事件。

  QDrag 类的常用信号说明如下:

actionChanged(action:Qt.DropAction)
targetChanged(newTarget:QObject)
import sysfrom PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton, QFrame
from PySide6.QtWidgets import QHBoxLayout
from PySide6.QtGui import Qt, QDrag
from PySide6.QtCore import QPointF, QMimeDataclass MyPushButton(QPushButton):def __init__(self, parent=None):super().__init__(parent)def mousePressEvent(self, event):"""鼠标按键事件"""# 1.如果是鼠标左键按下if event.button() == Qt.MouseButton.LeftButton:# 2.创建拖拽类self.drag = QDrag(self)# 3.设置热点位置self.drag.setHotSpot(QPointF.toPoint(event.position()))# 4.获取数据mineData = QMimeData()self.drag.setMimeData(mineData)# 5.开启拖放操作self.drag.exec()class MyFrame(QFrame):def __init__(self, parent=None):super().__init__(parent)# 1.允许拖放操作self.setAcceptDrops(True)# 2.设置分割线方向self.setFrameShape(QFrame.Shape.Box)# 3.创建按钮控件self.button_1 = MyPushButton(self)self.button_1.setText("button 1")self.button_1.move(100, 100)self.button_2 = MyPushButton(self)self.button_2.setText("button 2")self.button_2.move(200, 200)def dragEnterEvent(self, event):self.child = self.childAt(QPointF.toPoint(event.position()))event.accept()def dragMoveEvent(self, event):if self.child:self.child.move(QPointF.toPoint(event.position()) - self.child.drag.hotSpot())def dropEvent(self, event):if self.child:self.child.move(QPointF.toPoint(event.position()) - self.child.drag.hotSpot())class MyWidget(QWidget):def __init__(self):# 1.调用父类Qwidget类的__init__()方法super().__init__()# 2.设置成接受拖放事件self.setAcceptDrops(True)# 3.调用setupUi()方法初始化页面self.setup_ui()def setup_ui(self):# 1.设置窗口对象大小self.resize(700, 500)self.frame_1 = MyFrame(self)self.frame_2 = MyFrame(self)layout = QHBoxLayout(self)layout.addWidget(self.frame_1)layout.addWidget(self.frame_2)if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建一个窗口window = MyWidget()# 3.展示窗口window.show()# 4.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

4.4、剪贴板

  剪贴板 QClipboard 类似于拖放,可以在不同的程序间用复制和粘贴操作来传递数据。QClipboard 位于 QtGui 模块中,继承自 QObject 类,用 QClipboard(parent=None) 方法可以创建剪贴板对象。可以直接往剪贴板中复制文本数据、 QPixmap 和 QImage,其他数据类型可以通过 QMimeData 来传递。

  剪贴板 QClipboard 的常用方法如下所示。

setText(text:str, mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> None               # 将文本赋值到剪贴板
text(mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> str                             # 从剪贴板上获取文本
text(subtype:str, mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> Tuple[str, str]    # 从subtype指定的数据类型中获取文本
setPixmap(pixmap:QPixmap, mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> None       # 将QPixmap图像复制到剪贴板上
pixmap(mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> QPixmap                       # 从剪贴板上获取QPixmap图像
setImage(image:QImage, mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> None          # 将QImage图像复制到剪贴板上
image(mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> QImage                         # 从剪贴板上获取QImage图像
setMimeData(data:QMimeData, mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> None     # 将QMimeData数据复制到剪贴板上
mimeData(mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> QMimeData                   # 从剪贴板上获取QMimeData数据
clear(mode:QClipboard.Mode=QClipboard.Mode.Clipboard) -> None                           # 清空剪贴板

  剪贴板 QClipboard 的常用信号如下所示。

changed(mode:QClipboard.Mode=QClipboard.Mode.Clipboard)     # 剪贴板模式改变时发射信号
dataChanged()                                               # 剪贴板数据改变时发射信号
findBufferChanged()                                         # 在查找缓冲区被更改时发射信号。这只适用于macOS。
selectionChanged()                                          # 选择被改变时发射信号

五、窗口和控件的常用事件

  窗口和控件的常用事件包括窗口或控件的隐藏、显示、移动、缩放、重绘、关闭、获得和失去焦点等,通常需要重写这些事件的处理函数,以便达到特定的目的。

5.1、显示事件和隐藏事件

  在用 show() 方法或 setVisible(True) 方法显示一个顶层窗口之前会发生 QEvent.Show 事件,调用 showEvent(QShowEvent) 处理函数,显示事件类 QShowEvent 只有从 QEvent 继承的属性,没有自己特有的属性。在用 hide() 方法或 setVisible(False) 方法隐藏一个顶层窗口之前会发生 QEvent.Hide 事件,调用 hideEvent(QHideEvent) 处理函数,隐藏事件类 QHideEvent 只有从 QEvent 继承的属性,没有自己特有的属性。

5.2、缩放事件和移动事件

  当一个窗口或控件的宽度和高度发生改变时会触发 QEvent.Resize 事件,调用 resizeEvent(QResizeEvent) 处理函数。缩放事件类 QResizeEvent 只有两个方法 oldSize()size(),分别返回缩放前和缩放后的窗口尺寸 QSize。

  当改变一个窗口或控件的位置时会触发 QEvent.Move 事件,调用 moveEvent(QMoveEvent) 处理函数。移动事件类 QMoveEvent 只有两个方法 oldPos()pos() ,分别返回窗口左上角移动前和移动后的位置 QPoint。

5.3、移入事件和移出事件

  当光标进入窗口时,会触发 QEvent.Enter 进入事件,进入事件的处理函数是 enterEvent(QEnterEvent);当光标离开窗口时,会触发 QEvent.Leave 离开事件,离开事件的处理函数是 leaveEvent(QEvent)。可以重写这两个函数,以达到特定的目的。

5.4、焦点事件

  当一个控件获得和失去键盘输入焦点时,会触发 QEvent.FocusIn 和 QEvent.FocusOut 事件,这两个事件的处理函数分别是 focusInEvent(QFocusEvent)focusOutEvent(QFocusEvent),焦点事件类 QFocusEvent 的方法有 gotFocus()lostFocus()reason()。当事件类型 type() 的值是 QEvent.FocusIn 时,gotFocus()方法的返回值是 True,当事件类型 type() 的值是 QEvent.FocusOut 时,lostFocus() 方法的返回值是 True;reason() 方法返回获得焦点的原因,其返回值的类型是 Qt.FocusReason,其值如下:

Qt.FocusReason.MouseFocusReason
Qt.FocusReason.TabFocusReason
Qt.FocusReason.BacktabFocusReason
Qt.FocusReason.ActiveWindowFocusReason
Qt.FocusReason.PopupFocusReason
Qt.FocusReason.ShortcutFocusReason
Qt.FocusReason.MenuBarFocusReason
Qt.FocusReason.OtherFocusReason

5.5、绘制事件

  绘制事件 QPaintEvent 是窗体系统产生的,在一个窗口首次显示、隐藏后又显示、缩放窗口、移动控件,以及调用窗口的 update()repaint()resize() 方法时都会触发 QEvent.Paint 事件。绘制事件发生时,会调用 paintEvent(QPaintEvent) 处理函数,该函数是受保护的,不能直接用代码调用,通常在 paintEvent(QPaintEvent) 处理函数中处理一些与绘图、显示有关的事情。

  绘制事件类 QPaintEvent 只有两个方法 rect()region() 方法,分别返回被重绘的矩形区域 QRect 和裁剪区域 QRegion。

5.6、关闭事件

  当用户单击窗口右上角的 ❌ 按钮或执行窗口的 close() 方法时,会触发 QEvent.Close 事件,调用 closeEvent(QCloseEvent) 处理该事件。如果事件用 ignore() 方法忽略了,则什么也不会发生;如果事件用 accept() 方法接收了,首先窗口被隐藏,在窗口设置了 setAttribute(Qt.WA_DeleteOnClose,True) 属性的情况下,窗口会被删除。窗口事件类 QCloseEvent 没有特殊的属性,只有从 QEvent 继承来的方法。

5.7、定时器事件

  从 QObject 类继承的窗口和控件都会有 startTimer(ms:int,timerType=Qt.CoarseTimer) 方法和 killTimer(int) 方法。 startTimer() 方法会启动一个定时器,并返回 定时器的 ID 号。如果不能启动定时器,则返回值是 0,参数 ms 是 定时器的事件间隔,单位是毫秒;timerType 是 定时器的类型,可以取值如下:

Qt.TimerType.PreciseTimer
Qt.TimerType.CoarseTimer
Qt.TimerType.VeryCoarseTimer

  窗口或控件可以用 startTimer() 方法启动多个定时器,启动定时器后,会触发 timerEvent(QTimerEvent) 事件,QTimerEvent 是定时器事件类。用 QTimerEvent 的 timerId() 方法可以获取触发定时器事件的定时器 ID;用 killTimer(id:int) 方法可以停止定时器,参数是定时器的 ID。

import sysfrom PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton, QHBoxLayout
from PySide6.QtCore import Qt
from functools import partialclass MyWidget(QWidget):def __init__(self):# 1.调用父类Qwidget类的__init__()方法super().__init__()# 2.启动定时器timer_id_1 = self.startTimer(500, Qt.TimerType.PreciseTimer)timer_id_2 = self.startTimer(1000, Qt.TimerType.CoarseTimer)# 3.创建布局layout = QHBoxLayout(self)# 4.创建按钮控件button_1 = QPushButton("停止第一个定时器", self)button_2 = QPushButton("停止第二个定时器", self)# 5.将按钮添加到布局中layout.addWidget(button_1)layout.addWidget(button_2)# 6.定义信号与槽的连接# 使用lambad传递参数button_1.clicked.connect(lambda: self.kill_timer(timer_id_1))# 使用partial()函数传递参数button_2.clicked.connect(partial(self.kill_timer, timer_id_2))def kill_timer(self, value):# 关闭定时器if value:self.killTimer(value)def timerEvent(self, event):"""定时事件"""print(f"定时器ID: {event.timerId()}")if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建一个窗口window = MyWidget()# 3.展示窗口window.show()# 4.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

六、事件过滤

  一个控件或窗口的 event() 函数是所有事件的集合点,可以在 event() 函数中设置某种类型的事件是接收还是忽略,另外还可以用事件过滤器把某种事件注册给其他控件或窗口进行监控、过滤和拦截。

  一个控件产生的事件可以交给其他控件进行处理,而不是由自身的处理函数处理,原控件称为 被监测控件,进行处理事件的控件称为 监测控件。要实现这个目的,需要将被监测控件注册给监测控件。

  要把被监测对象的事件注册给监测控件,需要在被监测控件上安装监测器,被监测控件的监测器用 installEventFilter(QObject) 方法定义,其中 QObject 是监测控件。如果一个控件上安装了多个事件过滤器,则后安装的过滤器先被使用。用 removeEventFilter(QObject) 方法可以解除监测。

  要实现对被监测对象事件的过滤,需要在监测对象上重写过滤函数 eventFilter(QObject,QEvent),其中参数 QObject 是传递过来的被监测对象,QEvent 是被检测对象的事件类对象。过滤函数如果返回 True,表示事件已经过滤掉了;如果返回 False,表示事件没有被过滤。

import sysfrom PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtWidgets import QPushButton, QFrame
from PySide6.QtWidgets import QHBoxLayout
from PySide6.QtGui import Qt, QDrag
from PySide6.QtCore import QPointF, QMimeData, QEventclass MyPushButton(QPushButton):def __init__(self, parent=None, text=""):super().__init__(text, parent)def mousePressEvent(self, event):"""鼠标按键事件"""# 1.如果是鼠标左键按下if event.button() == Qt.MouseButton.LeftButton:# 2.创建拖拽类self.drag = QDrag(self)# 3.设置热点位置self.drag.setHotSpot(QPointF.toPoint(event.position()))# 4.获取数据mineData = QMimeData()self.drag.setMimeData(mineData)# 5.开启拖放操作self.drag.exec()class MyFrame(QFrame):def __init__(self, parent=None):super().__init__(parent)# 1.允许拖放操作self.setAcceptDrops(True)# 2.设置分割线方向self.setFrameShape(QFrame.Shape.Box)# 3.创建按钮控件self.button = MyPushButton(self, "button")self.button.move(100, 100)def dragEnterEvent(self, event):self.child = self.childAt(QPointF.toPoint(event.position()))event.accept() if self.child else event.ignore()def dragMoveEvent(self, event):if self.child:self.child.move(QPointF.toPoint(event.position()) - self.child.drag.hotSpot())class MyWidget(QWidget):def __init__(self):# 1.调用父类Qwidget类的__init__()方法super().__init__()# 2.设置成接受拖放事件self.setAcceptDrops(True)# 3.调用setupUi()方法初始化页面self.setup_ui()def setup_ui(self):# 1.设置窗口对象大小self.resize(700, 500)self.frame_1 = MyFrame(self)self.frame_2 = MyFrame(self)layout = QHBoxLayout(self)layout.addWidget(self.frame_1)layout.addWidget(self.frame_2)# 将按钮的事件注册到窗口上self.frame_1.button.installEventFilter(self)self.frame_2.button.installEventFilter(self)def eventFilter(self, watched, event):if watched ==  self.frame_1.button and event.type() == QEvent.Type.Move:self.frame_2.button.move(event.pos())return Trueif watched ==  self.frame_2.button and event.type() == QEvent.Type.Move:self.frame_1.button.move(event.pos())return Truereturn super().eventFilter(watched, event)if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建一个窗口window = MyWidget()# 3.展示窗口window.show()# 4.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

七、自定义事件

  用户定义自己的事件首先要创建一个继承自 QEvent 的类,并给自定义事件一个 ID 号(值),该 ID 号的值只能在 QEvent.User(值为 1000)和 QEvent.MaxUser(值为 65535)之间,且不能和已有的 ID 号相同。为保证 ID 号的值不冲突,可以用 QEvent 类的静态函数 registerEventType(hint:int=-1) 注册自定义事件的 ID 号,并检查给定的 ID 号是否合适,如果 ID 号合适,会返回指定的 ID 号值;如果不合适,则推荐一个 ID 号值。在自定义事件类中根据情况定义所需的属性和方法。

  需要用 QCoreApplication 的 sendEvent(receiver,event) 函数或 postEvent(receiver,event) 函数发送自定义事件,其中 receiver 是自定义事件的接收者,event 是自定义事件的实例化对象。用 sendEvent(receiver,event) 函数发送的自定义事件被 QCoreApplication 的 notify() 函数直接发送给 receiver 对象,返回值是事件处理函数的返回值;用 postEvent(receiver,event) 函数发送的自定义事件添加到事件队列中,它可以在多线程应用程序中用于在线程之间交换事件。

  控件或窗口上都有个 customEvent(event) 函数,用于处理自定义事件,自定义事件类的实例作为实参传递给形参 event,也可以用 event(event) 函数处理,在 customEvent(event) 函数或 event(event) 函数中根据事件类型进行相应的处理,也可用事件过滤器来处理。

from PySide6.QtWidgets import QApplication
from PySide6.QtCore import QEvent, QCoreApplicationclass CustomEvent(QEvent):# 自定义事件的IDCustomEventType = QEvent.Type(QEvent.registerEventType())def __init__(self, data=None):super().__init__(CustomEvent.CustomEventType)self.data = dataclass MyWidget(QWidget):def customEvent(self, event):"""自定义事件的处理函数"""if isinstance(event, CustomEvent):print(f"Received custom event with data: {event.data}")if __name__ == "__main__":# 1.创建一个QApplication类的实例app = QApplication(sys.argv)# 2.创建并分发自定义事件event = CustomEvent(data="Hello, Custom Event!")# 3.指定自定义事件的接收者receiver = MyWidget()# 4.使用QCoreApplication.postEvent来发送事件QCoreApplication.postEvent(receiver, event)# 5.进入程序的主循环并通过exit()函数确保主循环安全结束sys.exit(app.exec())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/870248.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025上半年

孩子们,正睿补习计划重启了。 自建题单:ZR 2022 summer B - Virtual Judge P10447 最短 Hamilton 路径 - 洛谷 | 计算机科学教育新生态 求从 \(1\) 号点出发恰好经过每个点一次并且最终回到 \(1\) 号点的最短路径。 设 \(dp_{i,s}\) 表示恰好经过了集合 \(s\) 中的点一次,当…

Agent FFT

Agent FFT请你根据 https://www.cnblogs.com/CDOI-24374/p/17733240.html 这篇文章,仿照写一个好的,以下是一篇仿照《Azune FFT》风格的文章: Azune FFT:异界之战 可能是 Azune 童话系列。感谢 int_R 提供灵感与素材,让奇幻之光照亮一切! ——题记 「报告,INQ。已抵达 …

2025/1/16

今天继续学习了Android开发的相关知识,做手机端的app今天学的是用xml文件控制页面,类似javaweb里面的前端,有许多标签,还解决了运行卡退的一个小问题,需要定义一个主题。

CICD Day9、Argo CD增强持续交付

1、Argo CD简介在Jenkins CI/CD流程中的持续交付阶段,既部署到k8s集群阶段,使用kubectl工具来进行应用程序的部署和更新操作,但这种方式无法实时跟踪应用程序的状态。这将造成用户在CI/CD流程完成后需要额外操作kubernetes集群,以进一步查看应用程序的状态。为了解决这些问…

专为高性能计算和低功耗应用设计的MPF100T-1FCVG484E MPF100TL-FCSG325E MPF100TL-FCVG484I PolarFire FPGA产品系列

‌MPF100TL-FCG484E PolarFire FPGA是Microchip推出的一款高性能、低功耗的FPGA产品系列,特别适用于各种需要高性能计算和低功耗的应用场景‌。‌PolarFire FPGA是Microchip推出的一款高性能、低功耗的FPGA产品系列,特别适用于各种需要高性能计算和低功耗的应用场景‌。这些器…

wordpress 从服务器收到预料之外的响应。此文件可能已被成功上传。请检查媒体库或刷新本页。此响应不是合法的JSON响应。解决方法.210721

两种报错方式: 1.此响应不是合法的JSON响应。 2.从服务器收到预料之外的响应。此文件可能已被成功上传。请检查媒体库或刷新本页。 情况:媒体服务器上传小文件没问题,大一点的文件报这个错误。 原因:这是因为nginx限制了请求体大小 方案:需要在nginx的虚拟机配置文件中添加…

docker containner挂掉,无法exec进入bash,如何修改文件的终极解决方法.210730

场景: Nginx在bash里面配置的时候挂掉了,然后docker start不起来,exec bash进不去,造成无法再改里面的文件了 解决方法: 1,docker ps –a 可以查到所有docker,包括没有运行的,找到containner ID [root@hecs-29489 ~]# docker ps -a CONTAINER ID IMAGE COMMAND…

HP惠普笔记本重装系统无法引导无法进操作系统的终极解决方法.210804

F9进入BIOS-先进(Advanced)-安全引导配置- 启用传统支持和禁用安全引导.zstitle { width: 280px; text-align: center; font-size: 26px } .zsimgweixin { width: 280px } .zsimgali { width: 280px; padding: 0px 0px 50px 0px } .zsleft { float: left } .zsdiv { display:…

Feign与SpringCloud LoadBalancer实现负载均衡源码分析

SpringCloud LoadBalancer 众所周知,SpringCloud体系中负载均衡的组件有SpringCloud LoadBalancer和Ribbon,Ribbon也在逐渐的被替代掉,因为SpringCloud LoadBalancer性能更高,支持响应式 下面通过hard-coded体现一下SpringCloud的负载均衡 首先有一个【say-hello】服务,提…

JS — 判断语句与循环语句

js的判断语句与循环语句...(* ̄0 ̄)ノ判断语句JavaScript中的if-else语句与C++、Python、Java中类似。直接输出到控制台:test.html中的内容为: <script type="module">let score = 90;if (score >= 85) {console.log("A");} else if (score &g…

Living-Dream 系列笔记 第92期

最小路径点覆盖 在一张 DAG 上,求一个路径的集合,使得它们两两不相交,且覆盖所有的点。 结论:答案即为 \(总点数-最大匹配\)(于是 \(总点数-最大匹配=总点数-最小点覆盖=最大独立集=最大团=最小路径点覆盖\))。 证明: 不妨转换角度,从研究路径转为研究点。 因为路径两两…

毕设学习第四天之Java的注解和反射

注解(Annotation) Java 注解(Annotation)是一种特殊的语言构造,用于为代码元素(如类、方法、字段等)提供元数据,通常不直接影响程序的逻辑执行。它们可以被编译器、框架或工具解析,用于执行特定操作,如自动化配置、代码生成、验证等。Java 提供了内置的注解(如 @Overr…