2016-12-29 68 views
0

在我的項目中,我有一個QTreeView顯示項目從QStandardItemModel。每個項目都有數據存儲在多個UserRoles中。QTreeView編輯UserRole而不是DisplayRole雙擊

QStandardItem* item = new QStandardItem(); 
item->setIcon(iconByte); 
item->setData(3, Qt::UserRole+1); 
item->setData(name, Qt::UserRole+2); 
item->setData(data, Qt::UserRole+3); 
... and so on 

當對某一項目用戶雙擊,具有兩個線路的對話編輯顯示允許用戶編輯的UserRole數據的部分。當編輯停止時,編輯會運行一些邏輯,並根據新的UserRole數據生成顯示名稱。

但是,這非常繁瑣,很快。隨着對話不斷彈出和什麼,這是一個緩慢和醜陋的解決方案。

我現在想要完全移除對話框並在項目本身中顯示行編輯小部件。默認情況下,雙擊一個項目進行編輯只會顯示一個行編輯小部件來更改DISPLAY角色。不過,我想要兩行修改來更改這兩個USER角色。然後正常的邏輯繼續。

我該如何去修改QTreeView的編輯項目部分?

謝謝你的時間!

+0

利用第二列不是一個選項。顯示文本並不總是兩個並列的userrole數據。 – mrg95

回答

2

我會使用QStyledItemDelegate的自定義子類來解決這個問題。在您的QTreeView附近某處,您可以在用戶角色之間切換QComboBox;您的自定義委託會以某種方式被告知當前選擇了哪個用戶角色,並會攔截更新模型中數據的方法以設置適當的角色。

示例實現(沒有測試過,可能含有錯別字和錯誤):

class RoleSwitchingDelegate: public QStyledItemDelegate 
{ 
public: 
    explicit RoleSwitchingDelegate(QComboBox * roleSwitcher, QObject * parent = 0); 

    virtual void setEditorData(QWidget * editor, const QModelIndex & index) const Q_DECL_OVERRIDE; 
    virtual void setModelData(QWidget * editor, QAbstractItemModel * model, 
       const QModelIndex & index) const Q_DECL_OVERRIDE; 
private: 
    QComboBox * m_roleSwitcher; 
}; 

RoleSwitchingDelegate::RoleSwitchingDelegate(QComboBox * roleSwitcher, QObject * parent) : 
    QItemDelegate(parent), 
    m_roleSwitcher(roleSwitcher) 
{} 

void RoleSwitchingDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const 
{ 
    // Assuming the model stores strings for both roles so that the editor is QLineEdit 
    QLineEdit * lineEdit = qobject_cast<QLineEdit*>(editor); 
    if (!lineEdit) { 
     // Whoops, looks like the assumption is wrong, fallback to the default implementation 
     QStyledItemDelegate::setEditorData(editor, index); 
     return; 
    } 

    int role = m_roleSwitcher->currentIndex(); 
    QString data = index.model()->data(index, role).toString(); 
    lineEdit->setText(data); 
} 

void RoleSwitchingDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const 
{ 
    // Again, assuming the model stores strings for both roles so that the editor is QLineEdit 
    QLineEdit * lineEdit = qobject_cast<QLineEdit*>(editor); 
    if (!lineEdit) { 
     // Whoops, looks like the assumption is wrong, fallback to the default implementation 
     QStyledItemDelegate::setModelData(editor, model, index); 
     return; 
    } 

    int role = m_roleSwitcher->currentIndex(); 
    QString data = lineEdit->text(); 
    model->setData(index, data, role); 
} 

一旦你的委託,你只需將其設置爲視圖:

view->setItemDelegate(new RoleSwitchingDelegate(roleSwitchingComboBox, view)); 
+0

我從來沒有聽說過'QStyledItemDelegate'。我仔細閱讀了一些文檔,並查看了答案。我不認爲在角色之間切換QComboBox非常方便用戶。我真的想要2行編輯小部件。是否可以將自定義編輯器小部件傳遞給setEditorData? – mrg95

+0

是的,'QStyledItemDelegate'有'createEditor'方法,它返回'QWidget'子類。您可以根據角色返回不同的編輯器。 – Dmitry

+0

感謝您的幫助:D – mrg95