2016-12-29 1 views
0

In meinem Projekt habe ich eine QTreeView Anzeige von Elementen aus einem QStandardItemModel. Jeder Artikel enthält Daten, die in mehreren UserRoles gespeichert sind.QTreeView UserRole anstelle von DisplayRole nach Doppelklick bearbeiten

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 

Wenn der Benutzer doppelklickt auf ein Element, bearbeitet eine Dialog mit zwei Zeile zeigt den Benutzer ermöglicht wird, Teile der Userrole Daten zu bearbeiten. Wenn die Bearbeitung beendet wird, durchlaufen die Bearbeitungen eine gewisse Logik und ein Anzeigename wird basierend auf den neuen UserRole-Daten generiert.

Dies wird jedoch sehr schnell sehr langweilig. Mit ständig auftauchenden Dialogen und was auch immer, ist es eine langsame und hässliche Lösung.

Ich möchte jetzt den Dialog vollständig entfernen und die Zeile Widgets WITHIN der Artikel selbst anzeigen. Wenn Sie auf ein Element doppelklicken, um es zu bearbeiten, wird standardmäßig nur ein Linienbearbeitungswidget angezeigt, um die DISPLAY-Rolle zu ändern. Ich möchte jedoch, dass zwei Zeilenänderungen die beiden USER-Rollen ändern. Und dann geht die normale Logik weiter.

Wie würde ich den Bearbeitungsbereich einer QTreeView ändern?

Danke für Ihre Zeit!

+0

eine zweite Verwendung Spalte ist keine Option. Der Anzeigetext ist nicht immer zwei Userrole-Daten nebeneinander. – mrg95

Antwort

2

Ich würde eine benutzerdefinierte Unterklasse von QStyledItemDelegate verwenden, um dies zu lösen. Irgendwo in der Nähe Ihrer QTreeView könnten Sie eine QComboBox zwischen den Benutzerrollen wechseln; Ihr benutzerdefinierter Delegierter würde irgendwie darüber informiert, welche Benutzerrolle gerade ausgewählt ist und würde die Methode abfangen, die Daten im Modell aktualisiert, um die richtige Rolle festzulegen.

Eine beispielhafte Implementierung (nicht getestet, können Tippfehler und Fehler enthalten):

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); 
} 

Sobald Sie den Delegaten haben, müssen Sie es nur auf die Ansicht setzen:

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

Ich habe noch nie von 'QStyledItemDelegate' gehört. Ich habe ein wenig über die Dokumentation gelesen und über Ihre Antwort nachgedacht. Ich denke nicht, dass es sehr benutzerfreundlich ist, eine QComboBox zwischen den Rollen zu wechseln. Ich möchte wirklich 2 Zeilen bearbeiten Widgets. Ist es möglich, ein benutzerdefiniertes Editor-Widget an setEditorData zu übergeben? – mrg95

+0

Ja, 'QStyledItemDelegate' hat' createEditor'-Methode, die eine 'QWidget'-Unterklasse zurückgibt. Abhängig von der Rolle können Sie verschiedene Editoren zurückgeben. – Dmitry

+0

Danke für Ihre Hilfe: D – mrg95

Verwandte Themen