Russian Qt Forum

Qt => Model-View (MV) => Тема начата: sergek от Январь 31, 2022, 14:15



Название: [Решено] Задать данные для пользовательской роли (Qt::UserRole)
Отправлено: sergek от Январь 31, 2022, 14:15
Коллеги,
поясните, пожалуйста, как правильно задавать пользовательскую роль модели?
Я использую табличную модель MyModel, наследник QAbstractTableModel, для отображения данных - QTableView.
Пользовательская роль мне нужна для использования в делегате, в котором в зависимости от ее значения, создавать разные типы виджетов.

Я предполагал, что все это реализуется следующим образом (в представленном коде я опускаю несущественные места):

модель:
Код
C++ (Qt)
class MyTableModel : public QAbstractTableModel
{
   Q_OBJECT
 
public:
 
...
   int rowCount(const QModelIndex &parent = QModelIndex()) const override;
   bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
...
};
 
Код
C++ (Qt)
bool MyTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
   if (!index.isValid())
       return false;
 
   if (role == Qt::EditRole) {
       // FIXME: Implement me!
...
       return true;
   }
   else {
       QAbstractTableModel::setData(index, value, role);
       return true;
   }
   return false;
}
 
делегат:
Код
C++ (Qt)
class CComboDelegate : public QStyledItemDelegate
{
   Q_OBJECT
 
   // QAbstractItemDelegate interface
public:
   QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
...
};
 
Код
C++ (Qt)
QWidget *CComboDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   int type = index.data(Qt::UserRole);
 
   if(type == 0) {
       QComboBox* combo = new QComboBox(parent);
       return combo;
   } else if(type == 1) {
       QLineEdit* edit = new QLineEdit(parent);
       return edit;
   } else {
       return parent;
   }
}
 
задаем пользовательскую роль для 3-ей колонки таблицы, для объекта tableView (QTableView) задаем делегат:
Код
C++ (Qt)
 
   MyTableModel* model = ...;
   int column = 2;
   for(int i=0; i<model->rowCount(); i++) {
       QModelIndex index = model->index(i, column);
       model->setData(index, 0, Qt::UserRole);
   }
 
   CComboDelegate* delegate = new CComboDelegate(tableView);
   tableView->setItemDelegateForColumn(column, delegate);
 
К сожалению, в CComboDelegate::createEditor данные роли type не определены. Что я не так делаю?


Название: Re: Задать данные для пользовательской роли (Qt::UserRole)
Отправлено: kambala от Январь 31, 2022, 14:40
рекомендуется использовать роль на 1 выше: Qt::UserRole + 1, Qt::UserRole + 2 и т.д. (ну и обозвать их в каком-нить enum тоже неплохо бы), в остальном вроде все правильно

а ты куда-то сохраняешь данные для пользовательской роли (по коду не видно)? по волшебству они нигде не хранятся, ну и в data() надо возвращать значения для своих ролей.


Название: Re: Задать данные для пользовательской роли (Qt::UserRole)
Отправлено: sergek от Январь 31, 2022, 15:16
а ты куда-то сохраняешь данные для пользовательской роли (по коду не видно)? по волшебству они нигде не хранятся, ну и в data() надо возвращать значения для своих ролей.
Это вот так нужно делать? :-\ Да никуда не сохраняю, соответственно и не возвращаю... Меня сбил с толку этот пример: https://question-it.com/questions/1695492/kak-dobavit-raznye-tipy-delegatov-v-qtreeview (https://question-it.com/questions/1695492/kak-dobavit-raznye-tipy-delegatov-v-qtreeview).
Понятно. Тогда, для моей задачи проще в CComboDelegate добавить параметром этот тип и не париться с левыми ролями.


Название: Re: Задать данные для пользовательской роли (Qt::UserRole)
Отправлено: kambala от Январь 31, 2022, 15:45
там там используется QStandardItemModel, айтемы этой модели как раз хранят данные внутри себя


Название: Re: Задать данные для пользовательской роли (Qt::UserRole)
Отправлено: sergek от Январь 31, 2022, 15:57
Понял, спасибо!