首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在PyQt中大小调整小部件时禁用多个自动重绘?

如何在PyQt中大小调整小部件时禁用多个自动重绘?
EN

Stack Overflow用户
提问于 2012-11-25 15:18:28
回答 1查看 3.8K关注 0票数 5

我有一个小部件的PyQt4程序,其内容重绘非常慢(因为我的任务,没关系)。当我试图调整这些小部件的大小时,当鼠标未发布时,程序会尝试多次重绘。冻得太多了。

我希望禁用该自动重绘,并配置PyQt,使其仅在鼠标释放时重绘所有小部件(这意味着每一次调整大小都会进行一次重绘)。

怎么做?

Edit1. --我会看到它非常简单,就像这样:拖动线,当拖动时,所有的小部件都站起来。当您发布它时,小部件重绘。但我真的不确定这在PyQt4中是否可行。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-25 20:14:09

首先,我建议您确保,如果您在小部件中使用自定义画图事件,那么您在每个事件中都不会做太多的工作,只需要寻找一个带助解决方案。如果是这样的话,试着找到一种缓存或减少工作量的方法。否则..。

绘制不透明或不透明的决定是由平台的窗口管理器做出的。据我所知,没有一个简单的属性来切换这个特性。类似的东西存在于QSplitter上,只在释放句柄之后绘制。

我可以提供一种变通的方法,就是在没有调整大小的情况下,将更新延迟一段时间。这将给您的应用程序一些喘息空间,以减少油漆事件。

代码语言:javascript
复制
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毫秒启动一次以执行更新并停止自身。但是,每次发生另一个调整大小的事件时,它都会重新启动该定时器。其结果是计时器将继续被重置。使更新处于禁用状态,直到出现延迟。

试着按住鼠标,调整大小,等待,再调整一些大小。即使在鼠标关闭时也应该进行更新,但没有调整大小。调整延迟以适应。你可以控制使用bool标志打开和关闭功能。

这个例子也可以重新处理,使DelayedUpdater仅仅是一个QObject,它接受一些QWidget实例作为参数。然后,它将自己设置为该对象的eventFilter,并监视其resizeEvent。这样,您就不必仅仅为了添加这个子类普通的小部件了。您只需创建一个DelayedUpdater实例,并将其用作监视小部件的实用程序对象。

下面是一个使其成为助手对象的示例:

代码语言:javascript
复制
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)

请注意,我们只是在主窗口内的一些任意小部件上使用这一点。我们给它添加了一个延迟更新器,其内容如下:

代码语言:javascript
复制
self.delayer = DelayedUpdater(self.someWidget)

DelayedUpdater监视目标小部件的调整大小事件,并执行延迟更新。您可以扩展eventFilter以监视其他事件,比如移动。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13552345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档