Russian Qt Forum

Qt => Model-View (MV) => Тема начата: DOOMer от Апрель 25, 2015, 09:51



Название: QAbstractListModel + QTreeview - не отображаются чекбоксы [РЕШЕНО]
Отправлено: DOOMer от Апрель 25, 2015, 09:51
Доброго времени суток.

В приложении имеется модель, хранящая список сущностей. Сущности - простые объекты, хранят в себе текстовую строку и "флаг" - выбран\не выбран (Qt::Checkstate в качестве типа).

Для отображения списка использую QTreview, с двумя колонками - для вывода названия и чекбокса для выбора элементов списка, т.к. требуется допустить выбор нескольких элементов. Про SelectionMode  у вьюхи я в курсе, но по условиям ТЗ необходимо именно такое поведение - с выбором через чекбоксы.

Проблема в том, что чекбоксы у меня не рисуются, вместо них выводятся числовые значения поля @selected" обпределенного в классе элемента модели.

Код методов data() и setData() в модели следующий:

Код
C
QVariant GroupListModel::data(const QModelIndex &index, int role) const
{
   if (!index.isValid() || role != Qt::DisplayRole)
       return QVariant();
 
   switch (role) {
   case Qt::DisplayRole: {
       if (index.column() == 0) {
           return _modelData[index.row()]->name();
       }
   }
   case Qt::CheckStateRole: {
       if (index.column() == 1) {
           return _modelData[index.row()]->selected();
       }
   }
 
   default:
       break;
   }
 
   return QVariant();
}
 
bool GroupListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
   if (!index.isValid() || (flags(index) & Qt::ItemIsEditable) == 0) {
       return false;
   }
   qDebug() << "value " << value;
 
   switch (role) {
   case Qt::CheckStateRole: {
       Qt::CheckState state = static_cast<Qt::CheckState>(value.toUInt());
       _modelData[index.row()]->setSelected(state);
       Q_EMIT dataChanged(index, index);
       break;
    }
   default:
       break;
   }
 
   return true;
}
 

Метод flags(const QModelIndex &index) определен так:

Код
C
Qt::ItemFlags GroupListModel::flags(const QModelIndex &index) const
{
   if (!index.isValid())
       return 0;
 
 
   Qt::ItemFlags resultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
 
   if (index.column() == 1)
   {
       resultFlags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
   }
 
   return resultFlags;
}
 

Qt 5.4.1

В аттаче - минимальный собираемый пример, на основе кода из этого проекта.


Название: Re: QAbstractListModel + QTreeview - не отображаются чекбоксы
Отправлено: Авварон от Апрель 25, 2015, 09:58
навскидку
Код:
        if (index.column() == 1) {
            return _modelData[index.row()]->selected();
        }
колонка 1, а должно быть 0, походу. юзайте энумы для колонок


Название: Re: QAbstractListModel + QTreeview - не отображаются чекбоксы
Отправлено: DOOMer от Апрель 25, 2015, 11:00
В том то и дело что надо выводить чекбоксы в колонке 1 (в приведенном коде была опечатка, оставшаяся после пробы разных вариантов, в том  числе и попыток вывода чекбокса в колонку 0).


Название: Re: QAbstractListModel + QTreeview - не отображаются чекбоксы
Отправлено: PimenS от Апрель 25, 2015, 11:37
Вся проблема в этой части data

Код:
if (!index.isValid() || role != Qt::DisplayRole)
        return QVariant();

Попробуйте так:

Код:
QVariant GroupListModel::data(const QModelIndex &index, int role) const
{
    switch (role) {
    case Qt::EditRole: {
        if (index.column() == 1)
            return QVariant();
        break;
    }
    case Qt::DisplayRole: {
        if (index.column() == 0) {
            return _modelData[index.row()]->name();
        }
        break;
    }
    case Qt::CheckStateRole: {
        if (index.column() == 1) {
            return _modelData[index.row()]->selected();
        }
        break;
    }

    default:
        break;
    }

    return QVariant();
}


Название: Re: QAbstractListModel + QTreeview - не отображаются чекбоксы
Отправлено: DOOMer от Апрель 25, 2015, 12:17
Цитировать
Вся проблема в этой части data
Благодарю. Все встао на свои места.