2010-05-10 50 views
21

我有一個QTreeWidgetItem與兩列數據,有沒有什麼辦法可以使第二列可編輯?當我執行以下操作時:只做一列QTreeWidgetItem可編輯

QTreeWidgetItem* item = new QTreeWidgetItem(); 
item->setFlags(item->flags() | Qt::ItemIsEditable); 

所有列都可以編輯。

回答

6

看起來你將不得不放棄使用QTreeWidgetQTreeWidgetItem,並與QTreeViewQAbstractItemModel去。 「Widget」類是便捷類,它們是更抽象但更靈活的版本的具體實現。 QAbstractItemModel的電話號碼爲flags(QModelIndex index),您將在其中返回適合您的列的值。

+2

不一定(如果我沒有弄錯)。請參閱下面的答案。 – d11 2012-11-14 07:25:25

+0

這比下面發佈的NoEditDelegate解決方案更重要,我認爲這是最好的。 – 2015-08-20 12:54:06

+0

謝謝@David。我也提出了NoEditDelegate解決方案。看起來更整潔,更完整,我會推薦它用於多個編輯觸發器。 – d11 2015-12-01 08:50:14

0

根據行和列,設置樹小部件的子元素是否可編輯(樹的長度)。

+0

我該怎麼做? 'QTreeWidgetItem :: setFlags'不會將列作爲參數。我應該在'QTreeWidget'中做到這一點,如果是這樣的話? – 2010-05-10 11:46:57

8

看起來像標準的QTreeWidget不允許這樣做。我認爲有兩種方法可以做到這一點:

  1. 使用QTreeView則與化QAbstractItemModel派生自己的類,並覆蓋國旗的功能

  2. 使用帶QStandardItemModel一個QTreeView則。然後,當您添加的項目只需設置相應欄目,讓編輯:

下面是第二個選項的一些代碼:

QString x, y; 
QList<QStandardItem*> newIt; 
QStandardItem * item = new QStandardItem(x); 
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled); 
newIt.append(item); 
item = new QStandardItem(y); 
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsEditable); 
newIt.append(item); 
model->appendRow(newIt); 

我找到第二個方法簡單,但是這取決於有多少靈活性你想用你的模型。

1

我是PySide和Python的新手,但我可以通過註冊QTreeWidget獲取itemClicked回調函數。在回調中,檢查列並只調用'editItem',如果它是針對要允許編輯的列。

class Foo(QtGui.QMainWindow): 
... 
def itemClicked(self, item, column): 
    if column > 0: 
     self.qtree.editItem(item, column) 

通過不爲列0調用editItem,事件基本上被丟棄。

+0

現在嘗試按F2,您將能夠編輯據稱不可編輯的列;-) – 2015-08-20 12:49:29

18

最近我有同樣的問題,並發現其與所有EditTriggers,不僅DoubleClicked一個(和雙點擊信號連接)

創建一個委託,返回一個空指針的有效的解決方案編輯:

class NoEditDelegate: public QStyledItemDelegate { 
    public: 
     NoEditDelegate(QObject* parent=0): QStyledItemDelegate(parent) {} 
     virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { 
     return 0; 
     } 
    }; 

後來把它作爲一個自定義的委託爲您列

ui->parameterView->setItemDelegateForColumn(0, new NoEditDelegate(this)); 
+2

偉大的選擇。您還可以將委託分配給整個視圖,並通過檢查index.column()來檢查它是否爲阻塞列。你也可以通過重寫'index.internalPointer()'到'QTreeWidgetItem *'來獲得對QTreeWidgetItem本身的訪問權限,以便在編輯被阻止時進行更多的控制,比如只有當項目有子項時才阻止編輯(就像我的情況一樣) 。 – Phlucious 2016-06-23 23:21:16

+0

偉大的答案,小微調,您可以使用該委託一切: 虛擬QWidget的* createEditor(QWidget的*父,常量QStyleOptionViewItem和選項,常量QModelIndex和指數)常量{ 如果(index.column()> 0){ 返回0; } return QStyledItemDelegate :: createEditor(parent,option,index); }} – Dariusz 2018-03-06 12:47:26

3
class EditorDelegate : public QItemDelegate 
{ 
    Q_OBJECT 

public: 
    EditorDelegate(QObject *parent):QItemDelegate(parent){}; 
    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; 
}; 

QWidget* EditorDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const 
{ 
    if(index.column() == 1) 
    { 
     return QItemDelegate::createEditor(parent, option, index); 
    } 
    return nullptr; 
} 

QTreeWidget

myQTreeWidget::myQTreeWidget() 
{ 
    EditorDelegate *d = new EditorDelegate(this); 
    this->setItemDelegate(d); 
} 
+0

有兩件事:如果colums不應該被編輯,也許作爲'else'的一部分,則從createEditor()返回'nullptr'。並且將項目標誌設置爲'Qt :: ItemIsEditable'來表示應該編輯的項目,否則代理將不會被調用。 – 2016-05-19 12:01:48

22

您可以在QTreeWidget編輯使用一種解決方法使只有某些列:

1)將QTreeWidget到NoEditTriggers

2)editTriggers財產插入項目,設置QTreeWidgetItem對象的Qt:ItemIsEditable標誌

3)將以下插槽連接到QTreeWidget對象的「itemDoubleClicked」信號:

void MainWindow::onTreeWidgetItemDoubleClicked(QTreeWidgetItem * item, int column) 
{ 
    if (isEditable(column)) { 
     ui.treeWidget->editItem(item, column); 
    } 
} 

其中「isEditable」是您編寫的函數,它對可編輯的列返回true,對不可編輯的列返回false。

+0

對我來說最好的解決方案。謝謝! – 2015-03-02 01:18:06

+6

雙擊並不是開始編輯的唯一方法,但有很多其他編輯觸發器(任何鍵,編輯鍵(Windows/Linux上的F2),當前項目更改等等),具體取決於配置(setEditTriggers)。所以這似乎有點不完整。 – 2015-08-20 12:48:18

+0

我同意@DavidFaure。我的解決方案很容易理解和測試,但需要一些工作才能實現多個編輯觸發器。如果需要多個編輯觸發器,我推薦使用user571167的NoEditDelegate解決方案。 – d11 2015-12-01 08:53:46

5

,我發現最簡單的方法是使用Qt :: ItemFlags

void myClass::treeDoubleClickSlot(QTreeWidgetItem *item, int column) 
{ 
    Qt::ItemFlags tmp = item->flags(); 
    if (isEditable(item, column)) { 
     item->setFlags(tmp | Qt::ItemIsEditable); 
    } else if (tmp & Qt::ItemIsEditable) { 
     item->setFlags(tmp^Qt::ItemIsEditable); 
    } 
} 

if的頂部通過OR增加了編輯功能,底部檢查是否有與AND,然後刪除它與一個XOR

通過這種方式,編輯功能在您需要時添加,並在您不需要時刪除。

然後決定連接此功能可將樹部件的itemDoubleClicked()信號,寫你的「編輯或不修改」裏面的isEditable()

+0

完美答案爲我來 – NDestiny 2015-07-21 10:37:27

0

我發現下面的代碼很適合我的需求,並做「還挺「停止 用戶編輯某些部分的列:

我基本上檢查角色,然後列。我只允許在第0列進行編輯。因此,如果用戶在其他列中進行編輯,那麼我會停止setData編輯,並且不會進行任何更改。

void treeItemSubclassed::setData(int column, int role, const QVariant &value) { 
    if (role == Qt::ItemIsEditable && column != 0){ 
     return; 
    } 
    QTreeWidgetItem::setData(column, role, value); 
} 
0

也許有點晚,但可能會有所幫助:

void MyClass::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column) { 
    Qt::ItemFlags flags = item->flags(); 
    if(column == 0) 
    { 
     item->setFlags(flags & (~Qt::ItemIsEditable)); 
    } 
    else 
    { 
     item->setFlags(flags | Qt::ItemIsEditable); 
    } 
} 

這裏0是你想只讀列的索引。

flags & (~Qt::ItemIsEditable) 

無論您的項目的前一個標記如何,都將ItemIsEditable位置設置爲0。

flags | Qt::ItemIsEditable 

無論前一個標誌如何都將其設置爲1。