Seite 1 von 1

[gelöst] QTreeView - Col > 0 -> Nicht klickbar

Verfasst: 7. Dezember 2010 17:01
von nebler
Guten Abend.

Ich hab folgendes Problem: Ich kann in der 2. Spalte mein Inhalt nicht selektieren bzw. bearbeiten.

Verwende QTreeView mit einem eigen geschriebenen QAbstractItemModel. Ich hab jetzt ein paar Sachen ausprobiert, bin aber irgendwie nicht schlauer daraus geworden.

Wenn ich bei den Flags immer:

Code: Alles auswählen

return Qt::ItemIsEnabled  | Qt::ItemIsSelectable | Qt::ItemIsEditable;
zurückgebe, hilfts mir das nicht wirklich. Die Zellen in der erste Spalte lassen sich editieren. Die anderen Zellen in den anderen Spalten dann nicht (hab auch mal spaßeshalber eine dritte eingefügt.)

Meine Struktur ist:
[Property Name] | [Property Value]
+ Topic
| |-Property 1 | Value 1
| |

Das lustige an der Geschichte ist, implementier ich die Methode buddy(), dann kann ich (ohne das ich es visuell bestätigt bekomme) eine Eingabe machen und bestätigen, dann wird setData() aufgerufen. (Wenn ich zB auf Property 1 klicke.)

Hat jemand eine Idee woran das hängt?

Qt-Version: 4.6.1 mit MS VS '08

Der Work-around der mit gerade einfällt, aber noch nicht getestet: Das ich einfach die Spalten tausche und in der Ansicht drehe (sofern das überhaupt geht).

Vielen Dank.

Mit freundlichen Grüßen

// code
Hier eine abgespekte Version, funktioniert dennoch nicht in der zweiten Spalte etwas editieren zu können.
MyItemModel-Implementierung

Code: Alles auswählen

#define PROPERTY_NAME_COL 0
#define PROPERTY_VALUE_COL 1

  MyItemModel::MyItemModel(QObject* parent): QAbstractItemModel(parent) {

  }

  QVariant MyItemModel::headerData ( int section, Qt::Orientation orientation, int role ) const {

    if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) {
      if ( section == PROPERTY_NAME_COL ) {
        return QObject::tr( "Property" );
      } else if ( section == PROPERTY_VALUE_COL ) {
        return QObject::tr( "Value" );
      }
    }

     return QVariant();  
  }

  QModelIndex MyItemModel::index( int row, int column, const QModelIndex& parent ) const {
    // check if we have that index at all
    if ( !hasIndex( row, column, parent ) ) {
      return QModelIndex();
    }

    // root node
    if( !parent.isValid() ) {
      Helper* helper = new Helper();
      //helper->parent = parent;
      return createIndex( row, column, helper );
    }
 
    return QModelIndex();
  }

  QModelIndex MyItemModel::parent( const QModelIndex& index ) const {
    if( index.isValid() ) {
      if( index.internalPointer() ) {
        Helper* helper = static_cast<Helper*>( index.internalPointer() );
        return helper->parent;
      }
    }

    return QModelIndex();
  }

  int MyItemModel::rowCount( const QModelIndex & parent ) const {
    return 5;
  }

  int MyItemModel::columnCount( const QModelIndex & parent ) const {
    if( parent.column() > 0 ) 
      return 0;

    return 2;
  }

  QVariant MyItemModel::data( const QModelIndex & index, int role ) const {
    if( index.isValid() && role == Qt::DisplayRole ) {
      return "Value";
    }   
    
    return QVariant();
  }

  Qt::ItemFlags MyItemModel::flags(const QModelIndex &index) const {
    if( index.isValid() ) 
      return Qt::ItemIsEnabled  | Qt::ItemIsSelectable | Qt::ItemIsEditable;

    return 0;
  }
Als Hilfe wurde die Klasse Helper definiert:

Code: Alles auswählen

class Helper {
    public:
      enum Type{ NONE = 0, TOPIC_NAME, PROPERTY_NAME, PROPERTY_VALUE };
      
      Type type;

      QModelIndex parent;

      Helper(): type( NONE ), parent() {}
};
Wenn das Model benötigt wird wird es hinzugefügt:

Code: Alles auswählen

ui._treeView->setModel( _myModel );
Lösung
Das Beispiel von Qt übernommen (also das auch als Datenstruktur ein Baum hinterlegt wird). Dadurch sind alle Probleme verschwunden, und es funktioniert wie erwartet. Nur, wieso diese Lösung nicht funktioniert hat, ist mir nicht ganz klar ...

edit 08.12.2010
Quellcode hinzugefügt

edit 09.12.2010
Als gelöst gekennzeichnet.

Verfasst: 7. Dezember 2010 17:04
von upsala
Code?

Verfasst: 8. Dezember 2010 08:42
von nebler
upsala hat geschrieben:Code?
Hinzugefügt, immer noch das gleiche Problem, auch mit der abgespeckten Variante. Kann nur die erste Spalte bearbeiten, die zweite geht nicht.

Verfasst: 8. Dezember 2010 09:33
von padreigh
Ich prophezeie schonmal ein Memory leak ... oder sammelst du die gesamten new Helpers bei invalidem ModelIndex irgendwo wieder auf und deletest die? Ausserdem macht das ganze (wegen des abspeckens?) so NULL Sinn.

Als Tipp: guck dir mal in der API createIndex(row,col,ITEM); genau an, so wie du as da machst kann es nicht klappen. Im normalfall sieht das eher so aus:

Code: Alles auswählen

QModelIndex DBM::index(int row, int column, const QModelIndex &parent)
            const
{
    // qDebug() << __PRETTY_FUNCTION__; // removed due to spam

    if (!hasIndex(row, column, parent))
        return QModelIndex();

    DBItem *parentItem; // DBItem knows holds its childs and knows if it got a parent

    if (!parent.isValid())
        parentItem = m_rootItem; // thats my member root item
    else
        parentItem = static_cast<DBItem*>(parent.internalPointer()); 

    // now Ive got the correct parent Item (in terms of "who holds the data"), now I get the desired child from it
    DBItem *childItem = parentItem->child(row);
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

Verfasst: 9. Dezember 2010 09:32
von nebler
padreigh hat geschrieben:Ich prophezeie schonmal ein Memory leak ... oder sammelst du die gesamten new Helpers bei invalidem ModelIndex irgendwo wieder auf und deletest die? Ausserdem macht das ganze (wegen des abspeckens?) so NULL Sinn.

Als Tipp: guck dir mal in der API createIndex(row,col,ITEM); genau an, so wie du as da machst kann es nicht klappen. Im normalfall sieht das eher so aus:
...
Hallo.

Vielen Dank für die Anmerkungen. Das Problem des Memory-Leaks ist behoben ^^ ... hab gar nicht dran gedacht, mir wars erstmal wichtig das die Darstellung und die Funktionen funktionieren. Ich hab mir die API angeschaut und verstehe nicht ganz, warum meine Lösung (bzw. sowie ich es probiert habe) nicht funktioniert hat. Also die Darstellung hat funktioniert nur das anklicken der weiteren Spalten nicht ... naja, mit dem Vorschlag bzw. mit dem wie man es normal macht, gehts (alles) problemlos.

Vielen Dank für die Hilfe und Anregungen.

Viele Grüße