代码之家  ›  专栏  ›  技术社区  ›  mins

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

  •  1
  • mins  · 技术社区  · 6 年前

    QMainWindow 包含子级 QWidget QLabel

    QLabel.resizeEvent() 处理程序被多次调用(假定是按照窗口的渐进放大进行,直到它占用整个桌面空间)。

    setPixmap() 缩放标签pixmap。这是一个相对较长的操作,会减慢进程。标签代码:

    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 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc Yonghwan Shin    6 年前

    问题是在窗口最大化的时候多次调用ResizeEvent,同样的次数就是您所说的缩放图像。一个可能的方法是除非经过一段时间,否则不要更新。在以下示例中,只调整大于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_())