2017-09-11 269 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

相關問題