Firstly, I would recommend that when using custom drawing events with your widgets, you do not do too much work in each case and just look for a solution for group help. If so, try finding a way to cache or reduce work. Otherwise...
The decision to draw opaque or not is one of the window managers of your platform. As far as I know, there is no simple attribute to switch this function. Something similar to this exists on QSplitter to draw only after releasing the handle.
I can suggest one workaround approach that should delay updating until it resizes for a certain period of time. This will give your application some respite to reduce paint events.
from PyQt4 import QtCore, QtGui import sys class DelayedUpdater(QtGui.QWidget): def __init__(self): super(DelayedUpdater, self).__init__() self.layout = QtGui.QVBoxLayout(self) self.label = QtGui.QLabel("Some Text") self.layout.addWidget(self.label, QtCore.Qt.AlignCenter) self.delayEnabled = False self.delayTimeout = 100 self._resizeTimer = QtCore.QTimer(self) self._resizeTimer.timeout.connect(self._delayedUpdate) def resizeEvent(self, event): if self.delayEnabled: self._resizeTimer.start(self.delayTimeout) self.setUpdatesEnabled(False) super(DelayedUpdater, self).resizeEvent(event) def _delayedUpdate(self): print "Performing actual update" self._resizeTimer.stop() self.setUpdatesEnabled(True) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) win = QtGui.QMainWindow() view = DelayedUpdater() win.setCentralWidget(view) win.show() view.delayEnabled = True app.exec_()
You will notice that when you quickly resize the main window, updates for the custom widget do not occur because we disabled them in the resize event. QTimer tries to start every 100 ms to perform an update and stop. But each time a different resize event occurs, it restarts this timer. The effect is that the timer will remain reset. leaving updates disabled until a delay occurs.
Try to hold with the mouse, resize a little, wait and resize a little more. Updating should occur even when your mouse is down, but you are not resizing. Adjust the delay. And you have control over turning the function on and off using the bool flag.
This example could also be reworked to make DelayedUpdater only a QObject, which takes some QWidget instance as an argument. Then he would set eventFilter for this object and check its resizeEvent . Therefore, you do not have to subclass regular widgets to add this. You would just make an instance of DelayedUpdater and use it as a utility object to monitor widgets.
Here is an example of creating a helper object:
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.someWidget = QtGui.QWidget() self.setCentralWidget(self.someWidget) self.layout = QtGui.QVBoxLayout(self.someWidget) self.label = QtGui.QLabel("Some Text") self.layout.addWidget(self.label, QtCore.Qt.AlignCenter) self.delayer = DelayedUpdater(self.someWidget) class DelayedUpdater(QtCore.QObject): def __init__(self, target, parent=None): super(DelayedUpdater, self).__init__(parent) self.target = target target.installEventFilter(self) self.delayEnabled = True self.delayTimeout = 100 self._resizeTimer = QtCore.QTimer() self._resizeTimer.timeout.connect(self._delayedUpdate) def eventFilter(self, obj, event): if self.delayEnabled and obj is self.target: if event.type() == event.Resize: self._resizeTimer.start(self.delayTimeout) self.target.setUpdatesEnabled(False) return False def _delayedUpdate(self): print "Performing actual update" self._resizeTimer.stop() self.target.setUpdatesEnabled(True)
Note that we only use this for some arbitrary widget inside our main window. We add a delay fix to it:
self.delayer = DelayedUpdater(self.someWidget)
DelayedUpdater monitors resize widget events for the target widget and performs pending updates. You can extend eventFilter to also keep track of other events, such as movement.