2011-11-17 3 views

risposta

18

In primo luogo, è necessario modificare TreeItem per tenere traccia dello stato controllato:

private: 
    ... 
    bool checked; 

e un setter e getter:

bool isChecked() const { return checked; } 
void setChecked(bool set) { checked = set; } 

Ora dovranno essere modificate in modo che il modello di che la vista conosce lo stato di controllo:

QVariant TreeModel::data(const QModelIndex &index, int role) const 
{ 
    if (!index.isValid()) 
     return QVariant(); 

    TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); 

    if (role == Qt::CheckStateRole && index.column() == 0) 
     return static_cast<int>(item->isChecked() ? Qt::Checked : Qt::Unchecked); 

    if (role != Qt::DisplayRole) 
     return QVariant(); 

    return item->data(index.column()); 
} 

e modificare il metodo di contrassegno del modello per consentire le viste sanno che il modello contiene elementi controllabili:

Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const 
{ 
    if (!index.isValid()) 
     return 0; 

    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; 

    if (index.column() == 0) 
     flags |= Qt::ItemIsUserCheckable; 

    return flags; 
} 

Penso che questo dovrebbe farlo. Se si desidera essere in grado di aggiornare lo stato di controllo TreeItem quando l'utente fa tic tac e deseleziona gli elementi, sarà necessario fornire il metodo QAbstractItemModel :: setData nel proprio TreeModel.

+0

Very Cool! Esattamente quello che stavo cercando. Tuttavia ho scoperto che avrei dovuto usare TreeWidget per quello che sto cercando di costruire. Grazie mille per il post comunque. – Drise

+0

Non che io possa proporre una soluzione migliore, ma il booleano manca ovviamente della meravigliosa TRISTATEZZA. (Ad esempio, per le cartelle parzialmente selezionate) – eMPee584

14

Ho convertito il precedente a PyQt per i miei scopi e ho pensato di condividere.

def data(self, index, role): 
    if not index.isValid(): 
     return None 

    item = index.internalPointer(); 

    if role == Qt.CheckStateRole and index.column() == self.check_col: 
     return int(Qt.Checked if item.isChecked() else Qt.Unchecked) 

    return super(TreeModel, self).data(index, role) 


def flags(self, index): 
    if not index.isValid(): 
     return None 

    if index.column() == self.check_col: 
     flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsUserCheckable 
    else: 
     flags = super(TreeModel, self).flags(index) 

    return flags 


def setData(self, index, value, role=Qt.EditRole): 
    if index.column() == self.check_col: 
     if role == Qt.EditRole: 
      return False 
     if role == Qt.CheckStateRole: 
      item = self.getItem(index) 
      item.setChecked(value) 
      self.dataChanged.emit(index, index) 
      return True 

    return super(TreeModel, self).setData(index, value, role) 
+0

Vecchio thread ma è possibile che si possa condividere l'intera classe? – atomSmasher

0

Ecco un altro esempio PyQt completa woking utilizzando QStandardItemModel:

model = QStandardItemModel() 
parent_item = model.invisibleRootItem() # type: QStandardItem 
for row in [ 
    (Qt.Unchecked, 'unchecked'), 
    (Qt.PartiallyChecked, 'partially'), 
    (Qt.Checked, 'checked') 
]: 
    checked, text = row 
    check_item = QStandardItem('') 
    check_item.setCheckable(True) 
    check_item.setCheckState(checked) 
    parent_item.appendRow([check_item, QStandardItem(text)]) 
treeview.setModel(model) 

Btw, questo dovrebbe funzionare anche per tutte le applicazioni C++.