QTreeView mit Checkbox

Alles rund um die Programmierung mit Qt
Antworten
DarkWotan
Beiträge: 65
Registriert: 18. Mai 2006 10:03

QTreeView mit Checkbox

Beitrag von DarkWotan »

Hallo,

ich suche nach einer Möglichkeit, die Einträge einer QTreeView in der ersten Spalte mit einer Checkbox zu versehen, über die man dann die Einträge markieren/auswählen kann.
Bisher habe ich nur bei QTreeWidgetItem eine Methode

Code: Alles auswählen

setFlags(Qt::ItemIsUserCheckable)
gefunden, mit der man das machen kann, ich möchte aber unbedingt MVC anwenden. Gibt es da etwas? In der Doku und auch hier werde ich nicht fündig.

MfG, Cedric
DarkWotan
Beiträge: 65
Registriert: 18. Mai 2006 10:03

Beitrag von DarkWotan »

Mittlerweile habe ich herausgefunden, wie man mein Vorhaben umsetzen kann.

Im Model, bei mir eine Unterklasse von QAbstractTableModel, muss die Methode data(), die auch für das Liefern der Daten zuständig ist, auch den Parameter role auf Qt::CheckStateRole prüfen und dann entweder QVariant() für Spalten ohne Checkbox oder Qt::Checked oder Qt::Unchecked liefern.
Dieser Teil ist zuständig für das Anzeigen der Checkboxen.
Allerdings möchte der Benutzer den Status bestimmt auch ändern können.
Dazu ist es nötig, flags() zu überschreiben, sodass eine Kombination der gewünschten Flags zusammen mit Qt::ItemIsUserCheckable geliefert wird.
Nun muss dem View aber auch noch ermöglicht werden, die Benutzereingaben anzunehmen und an das Model weiterzuleiten. Dafür muss beim Model noch die Methode setData() überschrieben werden. Ich gehe hierbei lediglich auf den Checkbox-Part ein.
In dieser Methode muss ebenfalls der Parameter role auf Qt::CheckStateRole überprüft werden und anschließend kann man die Checkbox beim übergebenen ModelIndex auf den in value gespeicherten Wert setzen. Wichtig ist, dass anschließend das Signal dataChanged() emittiert und true zurückgegeben wird. Beispiel:

Code: Alles auswählen

QVariant MyTableModel::data(const QModelIndex& index, int role) const
{
  if (!index.isValid() ||
      index.row() >= m_data->size())
    return QVariant();
  
  if (role == Qt::DisplayRole)
  {
    //hier die Daten zum Anzeigen zurückgeben
  }
  else if (role == Qt::CheckStateRole)
  {
    if (index.column() == 0)
      //das Feld checkState ist vom Typ Qt::CheckState
      return m_data->at(index.row()).checkState;
    
    return QVariant();
  }
  
  return QVariant();
}

bool MyTreeModel::setData(const QModelIndex& index, const QVariant& value,
                            int role)
{
  if (!index.isValid() || index.row() >= m_data->size())
    return false;  

  if (role == Qt::CheckStateRole)
  {
    (*m_data)[index.row()].checkState = static_cast<Qt::CheckState>(value.toInt());
    
    emit dataChanged(index, index);
  
    return true;
  }

  return false;
}

inline Qt::ItemFlags MyTreeModel::flags(const QModelIndex& index) const
{
  return Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
}
Viel Spaß ;-)

MfG, Cedric
Herakles
Beiträge: 1
Registriert: 7. Februar 2009 16:05

Beitrag von Herakles »

Hi,
das Beispiel, hat sehr geholfen.
Hab aber noch einen Fehler bei mir, die Häckchen der Checkboxen werden nicht überall korrekt angezeigt.
Kann mir jemand sagen was für Typen hinter m_data und checkState stecken?

Danke!
medi
Beiträge: 16
Registriert: 2. März 2006 13:25

Beitrag von medi »

Hallo,

mir hat das Beispiel auch gut geholfen.
Ich habe noch eine Frage dazu.
Muss ich die Methoden update(...) oder repaint(...) für QTreeView überschreiben, wenn ich die Checkbox zentriert darstellen möchte? Im Moment wird sie linksbündig in der Spalte des Baums angezeigt.

Vielen Dank
DarkWotan
Beiträge: 65
Registriert: 18. Mai 2006 10:03

Beitrag von DarkWotan »

Herakles hat geschrieben: Kann mir jemand sagen was für Typen hinter m_data und checkState stecken?
Sorry für die verspätete Antwort :-)
Soweit ich das jetzt noch rauslesen kann aus dem Beispiel ist m_data vom Typ

Code: Alles auswählen

std::vector<T>* m_data;
wobei T ungefähr so aussieht

Code: Alles auswählen

struct T
{
  Qt::CheckState checkState;
}
Antworten