简体   繁体   English

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

[英]PyQt: How to prevent processing multiple resize events when maximizing a window?

I have a QMainWindow containing a child QWidget containing itself a QLabel .我有一个QMainWindow包含一个子QWidget其中包含一个QLabel

When the window is maximized (eg by clicking the maximize icon on the window), the QLabel.resizeEvent() handler is called multiple times (supposedly to follow the progressive enlargement of the window until it takes the full desktop space).当窗口最大化时(例如通过单击窗口上的最大化图标), QLabel.resizeEvent()处理程序会被多次调用(据说是随着窗口的逐渐放大直到它占据整个桌面空间)。

The code in the event handler calls setPixmap() to scale the label pixmap.事件处理程序中的代码调用setPixmap()来缩放标签像素图。 This is a relatively long operation which slows the process.这是一个相对较长的操作,它减慢了过程。 Code for the label:标签代码:

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)

Is there a possibility to process the event only once, when the window has reached its final size?当窗口达到其最终大小时,是否有可能只处理一次事件?

The problem is that the resizeEvent is called many times in the time that the window is maximized, and that same number of times is what you call scale_image.问题是 resizeEvent 在窗口最大化的时间内被多次调用,而同样的次数就是你所说的 scale_image。 One possible possible is not to update unless a period of time passes.一种可能的做法是,除非经过一段时间,否则不更新。 In the following example only resizes for times greater than 100 ms (the time you must calibrate):在以下示例中,仅在大于 100 毫秒(您必须校准的时间)的时间调整大小:

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_())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM