2012-12-12 49 views
7

我有這樣的代碼:如何簡單地QFormLayout刪除行編程

myEdit = QLineEdit() 
myQFormLayout.addRow("myLabelText", myEdit) 

現在我有參照刪除行只myEdit

myQformLayout.removeRow(myEdit) 

但是沒有API爲。我可以使用.takeAt(),但我怎麼能得到這個論點?我如何找到標籤索引或myEdit的索引?

+0

你應該/必須使用指針(我認爲這是C++代碼)。 – UmNyobe

+1

嘗試removeWidget(myEdit) –

回答

9

你可以只安排小部件,它的標籤(如果有的話)進行刪除,並讓形式相應地調整自己。小部件的標籤可以使用labelForField來檢索。

Python的Qt代碼:

label = myQformLayout.labelForField(myEdit) 
    if label is not None: 
     label.deleteLater() 
    myEdit.deleteLater() 
+0

好吧,所以我應該調用layout.update(),因爲它看起來好像只有在deleteLater() – borovsky

+0

@borovsky之後。對不起,我不明白你的意思。在調用'deleteLater()'之前你在做什麼? – ekhumoro

+0

@borovsky。當一個小部件被刪除時,Qt也會遞歸地刪除它的所有子元素(這就是爲什麼確保小部件總是有一個父元素是個好主意)。在Python方面,垃圾回收器最終會進行清理。但是,如果您保留對某個對象的引用(例如實例屬性),則可能需要自己明確地刪除它。一旦Qt刪除了C++部分,Python部分就變得不可用,所以如果你試圖用它做任何事情,你將得到RuntimeErrors。 – ekhumoro

0

這實際上是一個很好的觀點...... addRow()沒有明確的反轉功能。

要刪除行,你可以做到以下幾點:

QLineEdit *myEdit; 
int row; 
ItemRole role; 
//find the row 
myQFormLayout->getWidgetPosition(myEdit, &row, &role); 
//stop if not found 
if(row == -1) return; 

ItemRole otheritemrole; 
if(role == QFormLayout::FieldRole){ 
    otheritemrole = QFormLayout::LabelRole; 
} 
else if(role == QFormLayout::LabelRole){ 
    otheritemrole = QFormLayout::FieldRole; 
} 

//get the item corresponding to the widget. this need to be freed 
QLayoutItem* editItem = myQFormLayout->itemAt (int row, role); 

QLayoutItem* otherItem = 0; 

//get the item corresponding to the other item. this need to be freed too 
//only valid if the widget doesn't span the whole row 
if(role != QFormLayout::SpanningRole){ 
    otherItem = myQFormLayout->itemAt(int row, role); 
} 

//remove the item from the layout 
myQFormLayout->removeItem(editItem); 
delete editItem; 

//eventually remove the other item 
if(role != QFormLayout::SpanningRole){ 
    myQFormLayout->removeItem(otherItem); 
    delete otherItem 
} 

注意,我刪除之前獲取的所有項目。這是因爲我不知道當物品被移除時他們的角色是否會改變。這種行爲沒有指定,所以我 安全。在qt設計器中,當您從表單中移除一個項目時,該行上的另一個項目將佔用所有空間(這意味着他的角色更改...)。

也許是有功能的地方,而不是隻有我重新發明車輪,但我做了一個破一個...

1

我的解決方案...

在頭文件

QPointer<QFormLayout> propertiesLayout; 

在CPP文件:

// Remove existing info before re-populating. 
while (propertiesLayout->count() != 0) // Check this first as warning issued if no items when calling takeAt(0). 
{ 
    QLayoutItem *forDeletion = propertiesLayout->takeAt(0); 
    delete forDeletion->widget(); 
    delete forDeletion; 
}