2017-06-10 57 views
0

我想根據QStandardItemModel結構中檢查項目的數量動態更改我的應用程序窗口上的滑塊數量。在PyQt5上添加/刪除QSlider小部件

我的應用程序窗口中有一個名爲slidersQVBoxLayout一個實例,其中當按下按鈕,我更新:

第一最終消除所有滑塊有:

self.sliders.removeWidget(slider) 

,然後創建一個新的集合。

相關的代碼:

def create_sliders(self): 
    if len(self.sliders_list): 
     for sl in self.sliders_list: 
      self.sliders.removeWidget(sl) 
    self.sliders_list = [] 
    for index in range(self.model.rowCount()): 
     if self.model.item(index).checkState(): 
      slid = QSlider(Qt.Horizontal) 
      self.sliders.addWidget(slid) 
      self.sliders_list.append(slid) 

原則似乎工作,但會發生什麼情況是怪異的刪除滑塊真的不消失,但它是因爲他們從底層佈局「斷開連接」。

創建時,滑塊在我調整主窗口大小時保持其他元素的位置。 但是,一旦它們被移除,它們就會佔據一個固定的位置,並且如果我減小窗口的大小,它會消失。 不幸的是,我在鏈接圖像時遇到了困難(它說格式不支持,當我嘗試從粘貼板鏈接),所以我希望這種描述足以突出問題。

我是否必須使用不同的步驟移除滑塊?

編輯

感謝@eyllansec他的迴音,它凝聚了一堆圍繞的話題對方回覆,這點我是沒能找到,因爲我不知道該方法deleteLater()這是關鍵的擺脫QLayout內部的小部件。

我將其標記爲我的選擇(嘿,這是唯一的一個,它的作品,畢竟!),但是我想提出我自己的代碼,也可以與最小的變化w.r.t.到我在開始時提出的建議。

這裏的關鍵是我正在使用metod QLayout.removeWidget(QWidget),這是我錯誤的想法,它會..er..Remove小部件!但實際上它所做的是(如果我理解的話),請從佈局實例中刪除它

這就是爲什麼它仍然掛在我的窗口,雖然它似乎斷開

Manual reference

而且,所提出的代碼比我所需要的,因爲它是一個遞歸超過佈局內容更加普遍原則上可以是其他QLayout對象或QWidgets(或甚至Qspacer),並且可以以層級結構(即QLayout等內的QWidgetQLayout)組織。

check this other answer

從那裏,使用遞歸和一系列if-then結構。

雖然我的情況要簡單得多,因爲我使用這個QVLayout實例來放置我的QSliders,這將是全部。所以,對我來說,我堅持我的名單,因爲我不喜歡QLayout.TakeAt(n)的形式主義,我不需要它。我很高興我在列表中創建的引用絕對可以使用。

最後,這是稍微改變的代碼,在這種情況下,對我的作品:

def create_sliders(self): 
    if len(self.sliders_list): 
     for sl in self.sliders_list: 
      sl.deleteLater() 
    self.sliders_list = [] 
    for index in range(self.model.rowCount()): 
     if self.model.item(index).checkState(): 
      slid = QSlider(Qt.Horizontal) 
      self.sliders.addWidget(slid) 
      self.sliders_list.append(slid) 

回答

1

沒有必要保存滑塊在列表中,他們可以通過佈局來訪問它被包含。我已經實現了一個刪除佈局中元素的函數。解決方案如下:

def create_sliders(self): 
    self.clearLayout(self.sliders) 

    for index in range(self.model.rowCount()): 
     if self.model.item(index).checkState(): 
      slid = QSlider(Qt.Horizontal) 
      self.sliders.addWidget(slid) 

def clearLayout(self, layout): 
    if layout: 
     while layout.count(): 
      item = layout.takeAt(0) 
      widget = item.widget() 
      if widget: 
       widget.deleteLater() 
      else : 
       self.clearLayout(item.layout()) 
      layout.removeItem(item) 
+1

它完美的工作,謝謝!我之所以使用滑塊列表,是因爲我必須對它們進行其他操作,並且我認爲這是保持對它們引用的一種簡潔方式。 我必須在代碼中進一步挖掘一下,以檢查您正在使用的方法,並且 - 正如您所說 - 可能我會直接從佈局中引用我的滑塊。 –