Russian Qt Forum

Qt => Model-View (MV) => Тема начата: ilnile от Июль 18, 2013, 22:52



Название: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: ilnile от Июль 18, 2013, 22:52
Добрый день. Подскажите почему у меня не реагирует на нажатия checkbox в унаследованной модели с переопределенными методами?

mymodel.h
Код:
#include <QSqlTableModel>
#include <QVariant>
#include <QBrush>

class myModel : public QSqlTableModel
{
    Q_OBJECT
public:
    explicit myModel(QObject *parent = 0);
    QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const;
    bool setData( const QModelIndex & index, const QVariant & value, int role);
    Qt::ItemFlags flags(const QModelIndex &index);


};

mymodel.cpp
Код:
#include "mymodel.h"
#include <QSqlRecord>
#include <QSqlTableModel>
#include <QDebug>

myModel::myModel(QObject *parent) :
    QSqlTableModel(parent)
{
}


QVariant myModel::data(const QModelIndex &index, int role) const
{
    QVariant value;

    if (index.column()==6)
    switch(role){
  case Qt::CheckStateRole:
      if (record(index.row()).value(index.column()).toInt()==0)
        value = Qt::Unchecked;
        else
        value = Qt::Checked;
        break;
    case Qt::DisplayRole:
        value = QVariant("");
                    break;
    }
    if (!value.isValid())
        value = QSqlTableModel::data(index,role);
    return value;
}


bool myModel::setData( const QModelIndex & index, const QVariant & value, int role)
{           
        if (index.isValid() && index.column() && role==Qt::CheckStateRole){

            QSqlRecord rec = record(index.row());
            bool chk = (value.toInt()==Qt::Checked);
            rec.setValue(index.column(),chk);

            return setRecord(index.row(),rec);
    }
        else
            return QSqlTableModel::setData(index,value,role);
}

Qt::ItemFlags myModel::flags(const QModelIndex &index)
{
       if(index.column()==6) return Qt::ItemIsUserCheckable  | QSqlTableModel::flags(index);
       return QSqlTableModel::flags(index);
}

Еще такой глюк: когда кликаю по полю с checkbox появляется spinbox рядом. После этого все остальные ячейки больше не редактируются до след обновления.


Название: Re: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: kambala от Июль 19, 2013, 00:41
надо отправлять сигнал dataChanged в setData() если сам обрабатываешь. и DisplayRole вообще не обрабатывай в data() для колонок.


Название: Re: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: ilnile от Июль 19, 2013, 12:07
С setData() разобрался. Но checkbox по прежнему не нажимаются. Такое чувство что я упускаю какой то маленький нюанс из-за которого все это происходит.

Когда нажимаю на checkbox он не нажимается, ведет себя как будто на поле наложена картинка (checkbox) и при нажатии на него он просто игнорирует его. Зато в поле появляется spinbox, если я изменяю в нем значение до 0, то checkbox снимает галочку.


Название: Re: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: kambala от Июль 19, 2013, 12:10
spinbox из воздуха не может появиться. у тебя свой делегат?

дебаггером проверял реальные значения чекбоксов?


Название: Re: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: ilnile от Июль 19, 2013, 12:58
Не знаю как это объяснить. Залил видео на ютуб.
http://youtu.be/q5Ntw4JBkik (http://youtu.be/q5Ntw4JBkik)


Название: Re: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: Bepec от Июль 19, 2013, 13:31
На мой взгляд такие вот кусты - ячейка редактируемая с числовым значением.

При нажатии на неё вызывается стандартный делегат для чисел - spinbox.

И да, checkBox у вас там только отрисовывается. Его как виджет там не существует.

Для нормального отщелкивания вам нужно или его создавать (в своём делегате), или возвращать для ячейки bool значение в displayRole.

Вроде должно сработать, хотя хз. Я давно не работал с моделями.


Название: Re: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: kambala от Июль 19, 2013, 13:32
несомненно, готовый проект для тестов выложить было сложнее.

попробуй сразу возвращать QVariant() для всех остальных ролей чекбоксов вместо вызова базового класса в data().

у меня при наследовании от QAbstractItemModel реализация такая:
Код
C++ (Qt)
QVariant DisenchantPreviewModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const
{
   switch (role)
   {
   case Qt::CheckStateRole:
       if (index.column() == CheckboxColumn)
           return _uncheckedIndexesSet.contains(index.row()) ? Qt::Unchecked : Qt::Checked;
       break;
   default:
       break;
   }
 
   return QVariant();
}
 
bool DisenchantPreviewModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/)
{
   if (role == Qt::CheckStateRole)
   {
       if (value.toBool())
           _uncheckedIndexesSet.remove(index.row());
       else
           _uncheckedIndexesSet += index.row();
 
       emit dataChanged(index, index);
       return true;
   }
 
   return false;
}


Название: Re: QSqlTableModel + checkBox = не реагирует на нажатия
Отправлено: ilnile от Июль 19, 2013, 15:01
Создал тестовый проект, инициализировал БД, прикрутил вьюху и делегат. Все отображается, нажимается, НО изменений в БД не происходит.
Пожалуйста подправьте код или подскажите какой сигнал нужно добавить.
http://rghost.ru/47526684 (http://rghost.ru/47526684)