PDA

View Full Version : QSqlQueryModel in QTableView with CheckBox in first column - how?



Huk
4th July 2009, 15:08
Hello everyone.

This is my first post here so please be “gentle” :)

I'm writing application that uses SQL database (Sqlite to be exact). In this program I have few QtableViews populated by QsqlQueryModels. Now I need to have check-boxes in first column of one of this views. I already read many posts about similar problems but I can't seem to understand how exactly should I proceed. Right now I have created custom delegate (for the first column) and model (see code below), and using them I can get check-box displayed, and can even check it and uncheck it... but it seems that state of this check-box is not saved – because as soon as I deselect cell the check-box is in, state resets. Even if my application loses focus, selection state resets...
I probably messed something up with either delegate or model, but I can't find it :(.

Please Help.

Here are my delegate and model:

checkablesqlquerymodel.h:


#ifndef CHECKABLESQLQUERYMODEL_H
#define CHECKABLESQLQUERYMODEL_H

#include <QSqlQueryModel>
#include <QMessageBox>
#include <QString>
#include <QAbstractItemModel>

#include <iostream>

class checkablesqlquerymodel : public QSqlQueryModel
{
Q_OBJECT

public:
checkablesqlquerymodel(QObject *parent = 0);

virtual Qt::ItemFlags flags ( const QModelIndex & index ) const;
//virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
//virtual void setEditorData ( QWidget * editor, const QModelIndex & index );
};

#endif // CHECKABLESQLQUERYMODEL_H


checkablesqlquerymodel.cpp:


#include <QtGui>
#include "checkablesqlquerymodel.h"

checkablesqlquerymodel::checkablesqlquerymodel(QOb ject *parent):QSqlQueryModel(parent){}

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

if(index.column()==0)
{
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
else
{
return QAbstractItemModel::flags(index);
}
}


patchesdelegate.h:


#ifndef PATCHESDELEGATE_H
#define PATCHESDELEGATE_H

#include <QSqlRelationalDelegate>
#include <QCheckBox>
#include <QEvent>
#include <QModelIndex>
#include <QPixmap>
#include <QSize>
#include <QSqlRelationalDelegate>
#include <QCheckBox>
#include <QComboBox>
#include <QtGui>
#include <QMessageBox>


class patchesdelegate : public QItemDelegate
{
public:
patchesdelegate(QObject *parent);

void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;

bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index);

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
};

#endif // PATCHESDELEGATE_H


patchesdelegate.cpp:


#include "patchesdelegate.h"

patchesdelegate::patchesdelegate(QObject *parent):QItemDelegate(parent)
{
}

void patchesdelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QMessageBox MB;
static int i;
QStyleOptionViewItemV3 opt = option;
opt.rect.adjust(0, 0, -1, -1); // since we draw the grid ourselves
QItemDelegate::paint(painter, opt, index);
if(index.column()==0)
{
bool value =index.data(Qt::UserRole).toBool();
QStyleOptionButton cbo;
cbo.rect=option.rect;
value ? cbo.state=QStyle::State_On : QStyle::State_Off;
cbo.text="Enabled";

QApplication::style()->drawControl(QStyle::CE_CheckBox,&cbo, painter);
}
}

bool patchesdelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
return QItemDelegate::editorEvent(event, model, option, index);
}


QWidget *patchesdelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QCheckBox *cb=new QCheckBox(parent);
return cb;
}


and to see how it looks like, please see attachment.

I use QTSDK-2009.02 currently on Debian 5.0. I write my code in QTCreator.

Thanks in advance.

P.S
Sorry for my English – it is not my native language.

ChrisW67
6th July 2009, 02:53
You probably need to add Qt::ItemIsUserCheckable to your flags for that column.

You should implement data() and setData() in your model for the Qt::CheckStateRole of the first column. Return (or accept) a Qt::CheckState value: code needs to worry about getting it in/out of the database.

The standard delegate will then draw a check box in the cell with the check state specified by the data(Qt::CheckStateRole) value.