2013-07-22 4 views
4

У меня есть модельКак установить QCheckBox в QAbstractItemModel?

class TreeModel : public QAbstractItemModel 

который я заселить с экземплярами моей TreeItem за исключением колонке == 1. В колонке 1 Я создал CheckBoxes:

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

    if (role != Qt::DisplayRole) { 
     if (role == Qt::CheckStateRole) { 
      if (index.column() == 1) { 
       if (index.row() == 1) { 
        return Qt::Unchecked; 
       } else 
        return Qt::Checked; 
      } 
     } 
     return QVariant(); 
    } 
    if (role == Qt::DisplayRole) { 
     if (index.column() != 1) { 
      TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); 
      return item->data(index.column()); 
     } 
    } 
    return QVariant(); 
    } 

я могу установить эти чекбоксы статуй Qt::Checked или Qt::Unchecked, но моя проблема: я не могу изменить их позже, когда они щелкают (однако setData называется с соответствующими index.column==1 и role==Qt::CheckStateRole). Я видел примеры с ItemDelegate - только это, похоже, работает. Это правда? Должен ли я использовать делегат в этом сценарии?

Вот моя setData() функция:

bool TreeModel::setData(const QModelIndex & index, const QVariant & value, 
     int role) { 
    if (role==Qt::CheckStateRole && index.column() == 1) { 
     TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); 
     QTreeWidgetItem *check = static_cast<QTreeWidgetItem*>(index.internalPointer()); 

     //if (item->data(index.column()) == Qt::Checked) 
     if (value == Qt::Checked){ 
      int i=1; 
      //check->setCheckState(1,Qt::Checked); //SIGSEGV 
     }else{ 
      //(item->data(index.column())) = Qt::Unchecked; 
      int i=2; 
      //check->setCheckState(1,Qt::Unchecked); 
     } 

     emit dataChanged(index, index); 
     return true; 
    } 
    emit dataChanged(index, index); 
    return true;; 
} 


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

    return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEditable; 
    } 

ответ

4

Я не понял концепцию Qt. Вы должны установить данные в УстановитьДанном (магазине проверка состояния), а затем заполнить модель в данных() с этим новым значением возвращается в флажок, так это:

УстановитьДанных()

bool TreeModel::setData(const QModelIndex & index, const QVariant & value, 
     int role) { 
    if (role==Qt::CheckStateRole && index.column() == 1) { 
     TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); 
     QTreeWidgetItem *check = static_cast<QTreeWidgetItem*>(index.internalPointer()); 

     if (value == Qt::Checked){ 
      int i=1; 
      checkedState_=Qt::Checked; 
     }else{ 
      int i=2; 
      checkedState_=Qt::Unchecked; 
     } 

данные()

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

    if (role != Qt::DisplayRole) { 
     if (role == Qt::CheckStateRole) { 
      if (index.column() == 1) { 
        return checkedState_; 
      } 
     } 
     return QVariant(); 
    } 
    if (role == Qt::DisplayRole) { 
     if (index.column() != 1) { 
      TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); 
      return item->data(index.column()); 
     } 
    } 
    return QVariant(); 
    } 
    emit dataChanged(index, index); 
    return true; 
} 
emit dataChanged(index, index); 
return true;; 

}

+0

Итак, что я сказал;) – Trompa

+0

спасибо тоже. сохранение данных в setData() было тем, что я пропустил – 4pie0

2

Это мне кажется странным, что вы возвращаете всегда один и тот же результат для данных (CheckStateRole)

if (role == Qt::CheckStateRole) { 
      if (index.column() == 1) { 
       if (index.row() == 1) { 
        return Qt::Unchecked; 
       } else 
        return Qt::Checked; 
      } 
     } 

Unchecked для (1,1) и проверяется на наличие (отличное от 1, 1)

вызывается setData(), но затем, когда представление запрашивает модель для значения, вы возвращаете всегда то же самое в data()

0

Использование примеров из @Trompa и @tinky_winky я сумел создать этот рабочий пример, как и @Trompa предложил нам нужно возвращать другое значение или сохранить это значение и получить его в нашем data(), чтобы получить фактическое состояние по этому конкретному индексу.

QVector<int> status; 
int SData::getStatus(int pos) 
{ 
    return status.at(pos); 
} 

void SData::setStatus(int pos,int value) 
{ 
    status.insert(pos, value); 
} 
QVariant STableModel::data(const QModelIndex &index, int role) const 
{ 
    if (!index.isValid()) 
     return QVariant(); 

    if (role == Qt::DisplayRole) 
     return rowList[index.row()][index.column()]; 
    else if (role == Qt::CheckStateRole && index.column() == 0) 
    { 

     int status = SData::instance().getStatus(index.row()); 
     if (status) 
      return Qt::Checked; 
     else 
      return Qt::Unchecked; 
    } 
    else 
     return QVariant(); 
} 

bool STableModel::setData(const QModelIndex &index, 
         const QVariant &value, int role) 
{ 
    if (!index.isValid() /*|| role != Qt::EditRole*/) 
     return false; 
    if (role == Qt::CheckStateRole) 
    { 
     if ((Qt::CheckState)value.toInt() == Qt::Checked) 
     { 
      SData::instance().setStatus(index.row(),1); 
      return true; 
     } 
     else 
     { 
      SData::instance().setStatus(index.row(), 0); 
      return true; 
     } 
    } 
Смежные вопросы