【问题标题】:How do I rebuild a gridLayout during resize?如何在调整大小期间重建 gridLayout?
【发布时间】:2016-03-22 00:59:21
【问题描述】:

我试图捕捉窗口的调整大小事件,当我这样做时,基本上会删除 gridLayout 中的所有小部件项目并重建行/列以适应新的调整大小的窗口。我无法使其正常工作,并且不确定这是否是我使用过的最佳方法。现在发生了两个问题:

  1. 当我将窗口大小调整为更大时,它似乎并没有正确删除项目、重建和添加列(有些项目删除,有些项目被添加,但似乎只是重叠并且永远不适合新的窗口大小)。

  2. 似乎在启动/创建窗口时调用了调整大小。

class Window (QtGui.QMainWindow):
    def __init__(self):
        super(Window, self).__init__()
        self.thumbs = []
        self.thumbWidgets = []

        self._resize_timer = None
        self.resizeCompleted.connect(self.handleResizeCompleted)

        self.setGeometry(100, 100, 800, 600)
        self.home()

    def home(self):

        self.centralwidget = QtGui.QWidget(self)

        '''MainLAYOUT
        '''
        self.mainLayout = QtGui.QVBoxLayout(self.centralwidget)

        self.thumb_tab_QGroupBox = QtGui.QGroupBox(self.centralwidget)

        '''GroupBoxLAYOUT
        '''
        self.vLayout =  QtGui.QVBoxLayout(self.thumb_tab_QGroupBox)
        self.vLayout.setObjectName("GroupVLayout")


        #Scroll Area
        self.thumbScrollArea = QtGui.QScrollArea(self.thumb_tab_QGroupBox)
        self.thumbScrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.thumbScrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.thumbScrollArea.setWidgetResizable(True)
        self.thumbScrollArea.setAlignment(QtCore.Qt.AlignLeft)
        self.thumbScrollArea.setObjectName("thumb_scrollArea")

        self.scrollAreaWidgetContents = QtGui.QWidget()
        self.scrollAreaWidgetContents.setMinimumSize(QtCore.QSize(840, scrollAreaX))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.thumbScrollArea.setWidget(self.scrollAreaWidgetContents)

        self.vLayout.addWidget(self.thumbScrollArea)
        self.mainLayout.addWidget(self.thumb_tab_QGroupBox)

        #Grid in Scroll Area
        self.gridLayoutWidget = QtGui.QWidget(self.scrollAreaWidgetContents)
        self.gridLayoutWidget.setObjectName("gridLayoutWidget")
        self.gridLayout_QGridLayout = QtGui.QGridLayout(self.gridLayoutWidget)
        self.gridLayout_QGridLayout.setObjectName("gridLayout")

        #Loads thumbnails
        self.getThumbnails()

        self.mainLayout.setAlignment(QtCore.Qt.AlignLeft)
        self.setCentralWidget(self.centralwidget)

    def resizeEvent(self, resizeEvent):
        self.updateResizeTimer(300)

    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 timerEvent(self, event):
        if event.timerId() == self._resize_timer:
            self.updateResizeTimer()
            self.resizeCompleted.emit()

    def handleResizeCompleted(self):
        print('resize complete')

        # Get new window size on resize
        width = self.centralwidget.frameGeometry().width()
        height = self.centralwidget.frameGeometry().height()

        thumbsPerRow = width / 200
        print "numThumbnails per Width", thumbsPerRow

        self.gridLayoutWidget.adjustSize()
        self.gridLayout_QGridLayout.maximumSize()

        for widget in self.thumbWidgets:
            print "Removing widget", widget
            self.gridLayout_QGridLayout.removeWidget(widget)
            #widget.deleteLater()

        self.populate(self.thumbWidgets, QtCore.QSize(200,200), thumbsPerRow)

    def queryThumbnailCount(self):
        ....
        ...
        ..
        return sizeX

    def getThumbnails(self):
        .....
        ....
        ...
        .
        self.createThumbWidgets(self.thumbs, QtCore.QSize(200,200))
        self.populate(self.thumbs, QtCore.QSize(200,200))

    def createThumbWidgets(self, pics, size, imagesPerRow=4, flags=QtCore.Qt.KeepAspectRatioByExpanding):
        for pic in pics:           
            label = QtGui.QLabel("")
            pixmap = QtGui.QPixmap(pic)
            pixmap = pixmap.scaled(size, flags)
            label.setPixmap(pixmap)
            self.thumbWidgets.append(label)


    #Add thumbnails to grid
    def populate(self, pics, size, imagesPerRow=6, flags=QtCore.Qt.KeepAspectRatioByExpanding):
        row = col = 0
        for widget in self.thumbWidgets:          
            print "Adding Image to column "+str(col)
            self.gridLayout_QGridLayout.addWidget(widget, row, col)
            col +=1
            if col % imagesPerRow == 0:
                row += 1
                col = 0        


GUI = Window()
GUI.show()

【问题讨论】:

  • 我做了类似的事情here。也许它会帮助你。
  • 此外,这似乎与在您的问题几小时后发布的this 问题非常相似。这是作业题吗?
  • 这很有趣...不,不是家庭作业。这是工作的东西。但奇怪的是有人遇到了和我一样的问题。我将尝试查看您的建议...其中是否有与重建网格有关的特定部分?好像比较长。
  • 第 293-307 行在我的示例中是最相关的。简而言之,您无需删除小部件并重新创建它们。只需将它们从布局中删除,然后以每行不同的数量重新添加它们。如果您删除所有 cmets 并仅查看 ToolPalette 类,我的代码不会那么长!
  • 好吧,我接受了您关于仅删除小部件而不是删除的建议,但我仍然没有看到任何区别。同样的两个问题,在调整大小时重新添加网格似乎有问题(它们有时相互重叠)。同样在初始启动时,调整大小被称为额外时间。如果您认为您可能知道我对行为不端的网格做错了什么,请更新上面的代码。

标签: resize pyqt rebuild qgridlayout


【解决方案1】:

使用QGraphicsView 可能会更好地实现这一点。

创建一个QGraphicsView 的子类,它也为自己创建一个QGraphicsScene。让它存储您希望它显示的像素图列表。覆盖子类中的resizeEvent 并清除QGraphicsScene 并使用QGraphicsPixmapItems 将所有像素图重新添加到场景中。在将它们添加到场景之前,请从 QGraphicsView.viewport() 获取总宽度和高度。您可以通过除以行/列来获得单个像素图的宽度/高度。然后在将每个像素图添加到场景之前对其进行缩放。

【讨论】:

  • 感谢...虽然这是另一种追求的途径,但我没有通过 QGraphicsScene 进行此操作,因为仅显示一些简单的缩略图似乎要复杂得多。如果我无法通过标签和网格布局弄清楚如何做到这一点,我将使用它作为备份。
  • 如果您不喜欢QGraphicsView,我建议您使用FlowLayout 中演示的here。它相当容易实现,可能适合您的需求。在调整大小期间,您甚至不需要专门做任何事情,布局会为您处理好。
  • 在这里找到了一个python版本... [link]ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/… 但是很遗憾,如果我把这个扔到scollArea中,它似乎不想合作,这是必要的。如果我调整大小,就坐在那里而不重新组织。
猜你喜欢
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 2018-05-07
  • 2012-10-05
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多