PDA

View Full Version : Checkbox in QListView



silmaril
26th January 2014, 06:04
I've looked at all the posts on this topic and I just cannot find a solution for this problem.

I have a QListView populated with a QSqlQueryModel and I need to add a checkbox to the list the my code displays all the records, but refuses to display the checkbox:



selectionSetModel *selectionViewModel = new selectionSetModel();

selectionViewModel->setQuery("select selected, selectionset, filecount, size from selectionsets");
selectionViewModel->setHeaderData(0, Qt::Horizontal, QObject::tr("Selected"));
selectionViewModel->setHeaderData(1, Qt::Horizontal, QObject::tr("Selection Set"));
selectionViewModel->setHeaderData(2, Qt::Horizontal, QObject::tr("File Count"));
selectionViewModel->setHeaderData(3, Qt::Horizontal, QObject::tr("Size"));

ui->selectionsetTableView->setModel(selectionViewModel);





#include <QtSql>
#include <QTextCharFormat>
#include <QtDebug>

#include "includes/selectionsetmodel.h"


selectionSetModel::selectionSetModel(QObject *parent) : QSqlQueryModel(parent)
{
}

Qt::ItemFlags selectionSetModel::flags(const QModelIndex &index) const
{
if(index.column()==0)
{
Qt::ItemFlags flags;
flags |= Qt::ItemIsSelectable;
flags |= Qt::ItemIsEditable;
flags |= Qt::ItemIsEnabled;
flags |= Qt::ItemIsUserCheckable;
return flags;
}
else
{
return QAbstractItemModel::flags(index);
}
}

QVariant selectionSetModel::data(const QModelIndex &index, int role)
{

QVariant value = QSqlQueryModel::data(index, role);
if (index.column() == 0)
{
if ( index.column() == 0 )
{
// Change this to suit your particular model storage backend
qDebug() << "Returned checked";

return Qt::Checked;
}
}
else
{
return value;
}
}

bool selectionSetModel::setData(const QModelIndex &index, const QVariant &value, int role )
{

QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
QString id = data(primaryKeyIndex, role).toString();

clear();

bool ok;
if (index.column() == 0) {
ok = setSelected(id, value.toInt());
}
refresh();
return ok;
}
//! [1]

void selectionSetModel::refresh()
{
setQuery("select selected, selectionset, filecount, size from selectionsets");
setHeaderData(0, Qt::Horizontal, QObject::tr("Selected"),Qt::CheckStateRole);
setHeaderData(1, Qt::Horizontal, QObject::tr("Selection Set"));
setHeaderData(2, Qt::Horizontal, QObject::tr("File Count"));
setHeaderData(2, Qt::Horizontal, QObject::tr("Size"));
}

//! [2]
bool selectionSetModel::setSelected(QString id, qint8 selected)
{
QSqlQuery query;
query.prepare("update selectionsets set id = ? where selected = ?");
query.addBindValue(id);
query.addBindValue(selected);
return query.exec();
}
//! [2]







#ifndef SELECTIONSETMODEL_H
#define SELECTIONSETMODEL_H

#include <QSqlQueryModel>



class selectionSetModel : public QSqlQueryModel
{
Q_OBJECT

public:
selectionSetModel(QObject *parent = 0);

Qt::ItemFlags flags(const QModelIndex &index) const;
bool setData (const QModelIndex &index, const QVariant &value, int role);
QVariant data(const QModelIndex &index, int role);

private:
bool setSelected(QString id, qint8 selected);
void refresh();
};


#endif // SELECTIONSETMODEL_H

anda_skoa
26th January 2014, 10:46
Your data() method needs to answer the request for role Qt::CheckStateRole for whatever column you want to have the checkbox displayed in.

Let assume column 0



QVariant selectionSetModel::data(const QModelIndex &index, int role)
{
if (index.column() == 0) {
if (role == Qt::CheckStateRole) {
QVariant selected = QSqlQueryModel::data(index, Qt::EditRole); // or Qt::UserRole
return selected.toInt() != 0; // assuming the value is 0 if not selected and != 0 if selected
}
return QVariant(); // no other data for this column
}
return QSqlQueryModel::data(index, role); // default behavior for other columns
}


Cheers,
_

silmaril
26th January 2014, 15:15
Thank you for your reply.

I applied the code you supplied and it still does not work.

I can see the int value in the list but it's not rendering the checkbox.



#include <QtSql>
#include <QTextCharFormat>
#include <QtDebug>

#include "includes/selectionsetmodel.h"


selectionSetModel::selectionSetModel(QObject *parent) : QSqlQueryModel(parent)
{
}

Qt::ItemFlags selectionSetModel::flags(const QModelIndex &index) const
{
if(index.column()==0)
{
Qt::ItemFlags flags;
flags |= Qt::ItemIsSelectable;
flags |= Qt::ItemIsEditable;
flags |= Qt::ItemIsEnabled;
flags |= Qt::ItemIsUserCheckable;
return flags;
}
else
{
return QAbstractItemModel::flags(index);
}
}

QVariant selectionSetModel::data(const QModelIndex &index, int role)
{
if (index.column() == 0) {
if (role == Qt::CheckStateRole) {
QVariant selected = QSqlQueryModel::data(index, Qt::EditRole); // or Qt::UserRole
return selected.toInt() != 0; // assuming the value is 0 if not selected and != 0 if selected
}
return QVariant(); // no other data for this column
}
return QSqlQueryModel::data(index, role); // default behavior for other columns
}

bool selectionSetModel::setData(const QModelIndex &index, const QVariant &value, int role )
{

QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);
QString id = data(primaryKeyIndex, role).toString();

clear();

bool ok;
if (index.column() == 0) {
ok = setSelected(id, value.toInt());
}
refresh();
return ok;
}
//! [1]

void selectionSetModel::refresh()
{
setQuery("select selected, selectionset, filecount, size from selectionsets");
setHeaderData(0, Qt::Horizontal, QObject::tr("Selected"),Qt::CheckStateRole);
setHeaderData(1, Qt::Horizontal, QObject::tr("Selection Set"));
setHeaderData(2, Qt::Horizontal, QObject::tr("File Count"));
setHeaderData(2, Qt::Horizontal, QObject::tr("Size"));
}

//! [2]
bool selectionSetModel::setSelected(QString id, qint8 selected)
{
QSqlQuery query;
query.prepare("update selectionsets set id = ? where selected = ?");
query.addBindValue(id);
query.addBindValue(selected);
return query.exec();
}
//! [2]

ChrisW67
26th January 2014, 20:20
You are returning a bool for Qt::CheckStateRole but the are four possible states. The values should be one of: Qt::Checked, Qt::Unchecked, Qt::Tristate (partially checked), or a null QVariant (for no check box at all)

silmaril
28th January 2014, 03:38
Sorry for the late response.

To be honest, I not sure how to do this. Could you update my code and post it back to this thread.

Regards

ChrisW67
28th January 2014, 04:49
Since you only seem to want on/off:


return selected.toInt()? Qt::Checked: Qt::Unchecked;