2017-09-11 217 views
1

我有3列的QGridLayout,这样PyQt的:更新QGridLayout正确删除所有项目,并加入当新

self.my_grid = QGridLayout() 
self.my_grid.setColumnStretch(2, 0) 

创建了10个项目, 它看起来如预期这样的填充网格后:

X X X 
X X X 
X X X 
X 

在某些事件网格项目改变,我试图抹掉所有项目,并添加新的:

def updateGrid(self, taskList): 

    # delete existing items from grid 
    for i in reversed(range(self.my_grid.count())): 
     widgetToRemove = self.my_grid.itemAt(i).widget() 
     widgetToRemove.setParent(None) 
     widgetToRemove.deleteLater() 

    # add new buttons 
    for task in tasklist: 
     btn = QPushButton(task) 
     self.my_grid.addWidget(btn) 

但后来它显示了这样一个空单元格:

X X 
X X X 
X X X 
X X 

并再次呼吁updateGrid之后,它有两个空单元格是这样的:

X 
X X X 
X X X 
X X X 

最后,再次迫使多了一个更新后我得到了我的预期:

X X X 
X X X 
X X X 
X 

如何避免空单元格?

回答

1

QGridLayoutQFormLayout类在删除小部件时不会删除它们的行。空行不占用任何垂直空间,但如果添加小部件而未指定行和列,则它们将放置在最后一个空列旁边。无法在这些布局中将行数和/或列重置为零。

在你的例子中,最后一行在零列中有一个项目。因此在下一次迭代中,第一个小部件将被添加到第一列。然后在下一次迭代中,最后一行将有两个项目,所以第一个小部件将被放置在第二列 - 等等,直到你回到你开始的位置。

为了解决这个问题,你可以重新使用现有的空行和列,并更新网格是这样的:

def updateGrid(self, taskList): 
    for i in reversed(range(self.my_grid.count())): 
     widgetToRemove = self.my_grid.itemAt(i).widget() 
     widgetToRemove.setParent(None) 
     widgetToRemove.deleteLater() 
    try: 
     index = 0 
     for row in range(self.my_grid.rowCount()): 
      for column in range(self.my_grid.columnCount()): 
       btn = QPushButton(taskList[index]) 
       self.my_grid.addWidget(btn, row, column) 
       index += 1 
    except IndexError: 
     pass 
+0

啊非常感谢这一点。优秀的答案。由于网格中的项目数量将随着每次重新加载项目而发生变化,因此我无法重新使用现有的行,但我想我将不得不更换完整的网格。 – user3729611

+0

@ user3729611。如果*行*的数量发生变化,但列数保持不变,那么我的答案仍然有效。通过一些小的更改,还应该可以更改列数。网格自动增长。 – ekhumoro

相关问题