2016-12-29 16 views
0

私のプロジェクトでは、QTreeViewの項目をQStandardItemModelから表示しています。各項目には、複数のUserRolesに格納されたデータがあります。QTreeViewダブルクリック時にDisplayRoleの代わりにUserRoleを編集する

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 

ユーザーが項目をダブルクリックすると、2行の編集を含むダイアログが表示され、ユーザーはUserRoleデータの一部を編集できます。編集が終了すると、編集内容がロジックを介して実行され、新しいUserRoleデータに基づいて表示名が生成されます。

しかし、これは非常に面倒です。ダイアログが絶えずポップアップしていて、それは遅くて醜い解決策です。

これで、ダイアログを完全に削除して、アイテム自体の中に行編集ウィジェットを表示したいと思います。デフォルトでは、編集するアイテムをダブルクリックすると、1行編集ウィジェットだけが表示され、DISPLAYロールが変更されます。しかし、私は2つの行の編集を2つのUSERの役割を変更する必要があります。そして、通常のロジックが続く。

QTreeViewの編集項目部分を変更するにはどうすればよいですか?

ありがとうございました!

+0

列はオプションではありません。表示テキストは必ずしも2つのユーザロールのデータではありません。 – 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'は' QWidget'サブクラスを返す 'createEditor'メソッドを持っています。役割に応じて異なるエディタを返すことができます。 – Dmitry

+0

ご協力ありがとうございます:D – mrg95

関連する問題