I have a grid of items in PyQt, and when the user modifies the window size I need to increase/decrease the number of columns accordingly. The number of rows are handled by a scrollarea, so I don't need to worry about changes in the y direction (if that matters).
Inside my implementation of QMainWindow, I know it's possible to override the resizeEvent() function, which will be triggered for any and all window adjustments. However, using that to rebuild the grid everytime is horribly inefficient. Just to test the function to see how it worked, I had resizeEvent merely print a string, and that caused my window adjustments to be slightly laggy and visually imperfect (jittery rather than smooth). I'll probably run a simple division operation on the window size to see if it has gotten larger or smaller enough to change the number of columns, but even that, when run a hundred times per adjustment, might cause lag issues. Rebuilding the entire grid might even take a second to do, so it would be preferable not to need to do it as the user is manipulating the window.
Is there a more efficient way to do it, or is resizeEvent my only option? Ideally, I'd like an event that triggered only once the user finished adjusting the window and not an event that triggers for practically every pixel movement as they happen (which can be hundreds or thousands of times per adjustment in the span of 1 second).
I'm using PyQt5, but if you're more familiar with PyQt4, I can figure out your PyQt4 solution in the context of PyQt5. Same for a C++ Qt4/5 solution.
It looks like the only real problem is detecting when resizing has completed. So long as this is carefully controlled, the actual laying out can be done in any way you like.
Below is a solution that uses a timer to control when a resize-completed signal is emitted. It doesn't appear to be laggy, but I haven't tested it with any complex layouts (should be okay, though).
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_())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With