まず、ウィジェットでカスタムペイントイベントを使用している場合は、各イベントで過度の作業を行わず、単にバンドエイドソリューションを探していることを確認することをお勧めします。このような場合は、作業をキャッシュまたは削減する方法を見つけてください。さもないと...
不透明に描画するかどうかの決定は、プラットフォームのウィンドウマネージャーによって行われます。私の知る限り、この機能を切り替えるための単純な属性はありません。これに似たものがQSplitter
、ハンドルを離した後にのみ描画するために存在します。
回避策の1つを提供できます。それは、一定期間サイズ変更が発生しなくなるまで更新を遅らせることです。これにより、アプリケーションにペイントイベントを減らすための余裕ができます。
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_()
メインウィンドウのサイズをすばやく変更すると、サイズ変更イベントでオフになっているため、カスタムウィジェットの更新が行われていないことがわかります。QTimerは、更新を実行して自身を停止するために100ミリ秒ごとに起動しようとしています。ただし、別のサイズ変更イベントが発生するたびに、そのタイマーが再起動します。その結果、タイマーは引き続きリセットされます。遅延が発生するまで、更新を無効のままにします。
マウスを押したまま、サイズを少し変更して、しばらく待ってから、もう少しサイズを変更してみてください。マウスが下がっていても、サイズを変更していない場合でも、更新が行われるはずです。それに合わせて遅延を調整します。また、ブールフラグを使用して機能のオンとオフを制御できます。
DelayedUpdater
この例は、引数としてQWidgetインスタンスを受け入れるQObjectだけを作成するように作り直すこともできます。次に、それ自体をそのオブジェクトのeventFilter
forに設定し、そのオブジェクトを監視しresizeEvent
ます。そうすれば、これを追加するためだけに通常のウィジェットをサブクラス化する必要はありません。DelayedUpdater
ウィジェットのインスタンスを作成し、それをユーティリティオブジェクトとして使用するだけです。
これをヘルパーオブジェクトにする例を次に示します。
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)
これは、メインウィンドウ内の任意のウィジェットで使用していることに注意してください。次の行を使用して、遅延アップデータを追加します。
self.delayer = DelayedUpdater(self.someWidget)
DelayedUpdater
は、ターゲットウィジェットのサイズ変更イベントを監視し、遅延更新を実行します。を展開してeventFilter
、移動などの他のイベントも監視できます。