使用PyQt,监控窗口大小及调整布局的首选(高效)方法是什么?
我在PyQt中有一个物品的网格,当用户调整窗口大小时,我需要相应地增加或减少列的数量。行的数量是通过一个滚动区域来处理的,所以我不需要担心垂直方向的变化(如果这有影响的话)。
在我实现的QMainWindow中,我知道可以重写resizeEvent()这个函数,它会在窗口调整时被触发。不过,每次都用这个函数来重建网格效率太低了。为了测试这个函数的效果,我让resizeEvent只是打印一个字符串,这样导致我的窗口调整时有点卡顿,视觉效果也不太好(看起来抖动而不是流畅)。我可能会对窗口大小进行简单的除法运算,看看它是否变大或变小到需要改变列数的程度,但即使这样,每次调整时运行一百次也可能会造成卡顿。重建整个网格可能需要一秒钟,所以最好在用户调整窗口时不需要这样做。
有没有更有效的方法,还是说resizeEvent是我唯一的选择?理想情况下,我希望有一个事件只在用户完成窗口调整后触发,而不是在他们每移动一个像素时就触发(这在一秒内可能会发生几百到几千次)。
我使用的是PyQt5,但如果你更熟悉PyQt4,我可以在PyQt5的上下文中理解你的PyQt4解决方案。C++的Qt4/5解决方案也是一样的。
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_())