PyQt:最大化窗口时如何防止处理多个调整大小事件?

时间:2018-12-29 20:43:23

标签: python pyqt pyqt5 qlabel qpixmap

我有一个QMainWindow,其中有一个孩子QWidget,其中有一个孩子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)

当窗口达到其最终大小时,是否只能将事件处理一次?

1 个答案:

答案 0 :(得分:1)

问题在于,在最大化窗口的过程中,多次调用了resizeEvent,而相同的次数就是您所说的scale_image。除非经过一段时间,否则可能不会更新。在以下示例中,调整大小的时间仅大于100 ms(必须校准的时间):

from PyQt5 import QtCore, QtGui, QtWidgets

class DisplayArea(QtWidgets.QLabel):
    def __init__(self):
        super().__init__()
        self.pix_map = QtGui.QPixmap()
        self._flag = False
        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 = QtGui.QPixmap.fromImage(image)
        self.scale_image()

    def scale_image(self):
        if self.pix_map.isNull():
            return
        scaled = self.pix_map.scaled(self.size(), QtCore.Qt.KeepAspectRatio)
        self.setPixmap(scaled)

    def resizeEvent(self, e):
        if not self._flag:
            self._flag = True
            self.scale_image()
            QtCore.QTimer.singleShot(100, lambda: setattr(self, "_flag", False))
        super().resizeEvent(e)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QMainWindow()
    da = DisplayArea()
    da.set_image(QtGui.QImage("logo.png"))
    w.setCentralWidget(da)
    w.show()
    sys.exit(app.exec_())