PyQt: Как предотвратить обработку нескольких событий изменения размера при максимизации окна? - PullRequest
0 голосов
/ 29 декабря 2018

У меня есть 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 голосов
/ 30 декабря 2018

Проблема в том, что resizeEvent вызывается много раз за время, когда окно развернуто, и это то же количество раз, что вы называете scale_image.Один из возможных вариантов - не обновлять, если не проходит период времени.В следующем примере изменяет размер только для времен, превышающих 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_())
...