6

我在 PyQt 中有一个项目网格,当用户修改窗口大小时,我需要相应地增加/减少列数。行数由滚动区域处理,所以我不需要担心 y 方向的变化(如果重要的话)。

在我的 QMainWindow 实现中,我知道可以覆盖 resizeEvent() 函数,该函数将在任何和所有窗口调整时触发。但是,每次都使用它来重建网格是非常低效的。只是为了测试该函数以了解它是如何工作的,我让 resizeEvent 仅打印一个字符串,这导致我的窗口调整稍微滞后并且视觉上不完美(抖动而不是平滑)。我可能会对窗口大小运行一个简单的除法运算,看看它是否变大或变小到足以改变列数,但即便如此,每次调整运行一百次时,也可能会导致滞后问题。重建整个网格甚至可能需要一秒钟的时间,所以当用户正在操作窗口时最好不要这样做。

有没有更有效的方法,或者 resizeEvent 是我唯一的选择?理想情况下,我想要一个仅在用户完成调整窗口后触发的事件,而不是在几乎每个像素移动发生时触发的事件(在 1 秒内每次调整可能会触发数百或数千次) .

我正在使用 PyQt5,但如果您更熟悉 PyQt4,我可以在 PyQt5 的上下文中找出您的 PyQt4 解决方案。对于 C++ Qt4/5 解决方案也是如此。

4

2 回答 2

5

看起来唯一真正的问题是检测调整大小何时完成。只要仔细控制,实际布局可以以您喜欢的任何方式完成。

下面是一个使用计时器来控制何时发出调整大小完成信号的解决方案。它似乎并不滞后,但我没有用任何复杂的布局对其进行测试(不过应该没问题)。

from PyQt4 import QtCore, QtGui

class Window(QtGui.QWidget):
    resizeCompleted = QtCore.pyqtSignal()

    def __init__(self):
        QtGui.QWidget.__init__(self)
        self._resize_timer = None
        self.resizeCompleted.connect(self.handleResizeCompleted)

    def updateResizeTimer(self, interval=None):
        if self._resize_timer is not None:
            self.killTimer(self._resize_timer)
        if interval is not None:
            self._resize_timer = self.startTimer(interval)
        else:
            self._resize_timer = None

    def resizeEvent(self, event):
        self.updateResizeTimer(300)

    def timerEvent(self, event):
        if event.timerId() == self._resize_timer:
            self.updateResizeTimer()
            self.resizeCompleted.emit()

    def handleResizeCompleted(self):
        print('resize complete')

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 300, 300)
    window.show()
    sys.exit(app.exec_())
于 2014-04-26T12:15:07.360 回答
0

我认为您需要FlowLayout为此目的,它会在调整包含它的小部件大小时自动调整列数。是文档FlowLayout这里是相同布局的 PyQt 版本。

于 2014-04-26T04:59:42.667 回答