我有一个
QMainWindow
包含一个子
QWidget
包含自身a
QLabel
当窗口最大化时(例如,通过单击窗口上的最大化图标),
QLabel.resizeEvent()
处理程序被调用多次(据说跟随窗口的逐渐放大,直到占据整个桌面空间)。
事件处理程序中的代码调用
setPixmap()
来缩放标签像素图。这是一个相对较长的操作,会减慢进程。标签代码:
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QLabel, QFrame, QGridLayout
from PyQt5.QtGui import QImageReader, QPixmap
class DisplayArea(QLabel):
def __init__(self):
super().__init__()
self.pix_map = None
self.init_ui()
def init_ui(self):
self.setMinimumSize(1, 1)
self.setStyleSheet("border:1px solid black;")
def set_image(self, image):
self.pix_map = QPixmap.fromImage(image)
self.scale_image(self.size())
def scale_image(self, size):
if self.pix_map is None:
return
scaled = self.pix_map.scaled(size, Qt.KeepAspectRatio)
self.setPixmap(scaled)
def resizeEvent(self, e):
self.scale_image(e.size())
super().resizeEvent(e)
当窗口达到其最终大小时,是否可以仅处理该事件一次?
当然可以!是对的,在窗口最大化时,PyQt 会多次调用
resizeEvent
,这可能会导致性能问题,尤其是当在该事件处理程序中执行耗时的操作(例如图像缩放)时。
可以使用以下两种方法来优化代码:
1. 使用
isMaximized()
方法
在
resizeEvent
处理程序中,可以检查窗口是否已最大化。如果是,则仅执行一次缩放操作。
def resizeEvent(self, e):
if self.parentWidget().isMaximized(): # 检查父窗口是否已最大化
self.scale_image(e.size())
super().resizeEvent(e)
2. 使用标志变量
可以使用一个布尔标志变量来跟踪是否已执行缩放操作。在
resizeEvent
处理程序中,仅当标志变量为
False
时才执行缩放操作。将窗口还原或调整大小后,将标志变量重置为
False
。
class DisplayArea(QLabel):
def __init__(self):
# ...
self.scaled_on_maximize = False # 添加一个标志变量
# ...
def resizeEvent(self, e):
if self.parentWidget().isMaximized() and not self.scaled_on_maximize:
self.scale_image(e.size())
self.scaled_on_maximize = True # 设置标志变量
elif not self.parentWidget().isMaximized():
self.scaled_on_maximize = False # 重置标志变量
super().resizeEvent(e)
这两种方法都可以有效地减少
resizeEvent
处理程序中
scale_image
方法的调用次数,从而提高应用程序的性能。
请注意,在上面的代码中,我们使用了
self.parentWidget()
来访问 QLabel 的父窗口。如果在其他地方使用此代码,请确保将其替换为对实际父窗口的引用。