pyQt QWidget'闪烁'调整大小和重绘

时间:2015-02-08 01:47:07

标签: python qt pyqt flicker qdockwidget

我正在寻找一种方法来最小化我的pyQt应用上的重绘'闪烁'。

我的应用程序是一个QMainWindow,包含两个QDockWidget派生对象(以及通常的各种工具。菜单和状态栏)。其中一个QDockWidgets *使用QGridLayout在每个网格元素中排列多个QGLWidget派生窗口。

当我调整MainWindow的大小时,整个安排会正确调整大小。然而,在QGLWidgets之间的空间中,我可以看到看起来像是一些部分呈现的奇怪形状的视图,MainWindow的一部分“轻弹”进入视图一瞬间然后正确渲染。我的应用程序通常用深色样式着色,但QGLWidgets之间的闪烁通常只是白色和黑色。我拖动Mainwindow边框越快,这个闪烁就越明显。让我强调一下,'闪烁'只存在于QGLWidget对象后面和后面,其他一切看起来都很好。

无论我是否在QGLWidgets中绘制了任何内容,闪烁都在那里,因此渲染没有太大的负担。

我有什么办法可以消除重绘(和调整大小)事件的闪烁吗?

我尝试将所有小部件着色为相同的深色,在某些小部件上使用.hide()和.show()进行着色,但它们似乎只会减慢过程并使其变得更糟。

  • 注意我发现我必须在QDockWidget中放置一个虚拟QWidget,因为QDockWidget不会接受(我猜它不支持)Layouts。也许这与此有关。

这是在Windows 7上运行的python 2.7的pyQt 4.10.1。我有几个月的pyQt经验

1 个答案:

答案 0 :(得分:1)

所以,按照上述建议,当您转到PyQt5和Python34并使用新的QtWidgets.QOpenGLWidget时,闪烁会消失。您可以使用新窗口小部件运行下面的代码,并且闪烁消失了,但是使用旧的QGLWidget(####行),在调整大小时,后台刷新非常烦人。

from PyQt5 import QtCore, QtGui, QtWidgets, QtOpenGL

class ImageGLView ( QtWidgets.QOpenGLWidget ):
####class ImageGLView ( QtOpenGL.QGLWidget ):   

    def __init__(self, parent = None ):
        print ( "ImageGLView.__init__" )

        QtWidgets.QOpenGLWidget.__init__( self, parent )
        ####QtOpenGL.QGLWidget.__init__( self, QtOpenGL.QGLFormat( QtOpenGL.QGL.SampleBuffers), parent )

        self.setStyleSheet( "QtOpenGL.QGLWidget {border-style: None; background-color: #404040; color:#FFFFFF }" )
        self.setToolTip ( "Image View" )


class TopWindow(QtWidgets.QMainWindow):
    def __init__ ( self, parent = None ):
        super( TopWindow, self).__init__(parent)

        self.initUI()
        self.initStyle()

    def initUI (self):
        self.setGeometry ( 0, 0, 800, 600 )
        self.setWindowTitle ( 'Test pyQt5')
        self.setWindowIcon ( QtGui.QIcon( 'images\Curlyhoward.jpg' ) )
        self.setStyleSheet("QWidget {background-color: #404040; color:#FFFFFF }" )
        self.populateFrames()


    def initStyle(self):
        palette = self.palette()
        palette.setColor(self.backgroundRole(), QtGui.QColor(64,64,64) )
        self.setToolTip( "Liver Fat Fraction")
        self.setPalette(palette )

        self.setDockOptions(QtWidgets.QMainWindow.AnimatedDocks | QtWidgets.QMainWindow.AllowNestedDocks)


    def populateFrames(self ):       
        self.controlsPane = QtWidgets.QDockWidget()
        self.controlsPane.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable | QtWidgets.QDockWidget.DockWidgetMovable)
        self.controlsPane.setAllowedAreas( QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea )
        self.controlsPane.setStyleSheet("QWidget {background-color: #404040; color:#FFFFFF }" )        
        self.addDockWidget( QtCore.Qt.RightDockWidgetArea, self.controlsPane )     

        self.imageDisplayPane = QtWidgets.QDockWidget()
        self.imageDisplayPane.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable | QtWidgets.QDockWidget.DockWidgetMovable)
        self.imageDisplayPane.setAllowedAreas( QtCore.Qt.RightDockWidgetArea | QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.TopDockWidgetArea | QtCore.Qt.BottomDockWidgetArea )
        self.imageDisplayPane.setStyleSheet("QWidget {background-color: #FAFAFA; color:#0f0f0f }" )        

        numCols = 2
        numRows = 2

        self.imageDisplayPane.gridLayout = QtWidgets.QGridLayout()      

            #### ...seems like a QDockWidget needs to have a single widget in which it can then accept the layout...
            self.imageDisplayPane.paneContent = QtWidgets.QWidget()
            self.imageDisplayPane.paneContent.setStyleSheet("QWidget {background-color: #404040; color:#FFFFFF }" )
            self.imageDisplayPane.setWidget( self.imageDisplayPane.paneContent )            
            self.imageDisplayPane.paneContent.setLayout( self.imageDisplayPane.gridLayout )                                                                                

            for row in range ( numRows ):
                for col in range ( numCols ):                
                    view = ImageGLView( self )
                    self.imageDisplayPane.gridLayout.addWidget (view, row, col )                        
            self.addDockWidget( QtCore.Qt.LeftDockWidgetArea, self.imageDisplayPane )    


def main():
    app = QtWidgets.QApplication( sys.argv )
    app.setStyle ( "windows ")

    mainWindow = TopWindow()
    mainWindow.show()

    mainWindow.raise_()
    app.exec_()


if __name__ == '__main__':
    main()