PDA

View Full Version : boolean field checkbox QTableView



skuda
11th February 2009, 00:00
Hello,
I have a QTableView with a QSqlRelationalTableModel and i want the boolean colums to be checkboxes in display and edit, I have searching the forum but i have not understand the full picture here i think, i have tried two ways to do that:

-Create a QItemDelegate subclass and reimplement the methods createEditor, setEditorData, setModelData and updateEditorGeometry to represent a checkbox on edit.

-Create a QSortProxyModel subclass and reimplement flags to add a Qt.ItemIsUserCheckable on the boolean column an check for Qt::CheckStateRole in data method to reply with the boolean value of the column.

If i use the sortproxymodel i get the checkbox in display with the correct values but i still see the "true, false" strings and to change the value i get a combobox with the values true or false.

If i use the delegate i get the checkbox to edit on doble click but i dont see checkboxes in display mode, only my well know "true, false" strings.

If i use the delegate and the sortproxymodel i get a checkbox on the left of the cell on display mode and when i try to change the value i see other checkbox at the right of the first where i can change the value, after i commit the change the second checkbox is gone and the left display checkbox shows the change.

Do i have any way to have a checkbox column in display and edit (the same) and not see the text "true, false"?

Thanks in advance.

skuda
11th February 2009, 19:36
With a little help from qt-interest mailinglist i have get the effect i want, and without use persistenteditor or delegate, i have subclassed QSortFilterProxyModel and react there to Qt.CheckStateRole, because i am using the same model in one QDataWidgetMapper, i paste the code here to anyone with this problem in the future, is is python but easily interpretable.


class GenericSortProxyModel(QSortFilterProxyModel):
def __init__(self, parent):
super(GenericSortProxyModel, self).__init__()
self.booleanSet = set()
self.nullVariant = QVariant()

def setParametros(self, booleanColumns=None):
if booleanColumns:
for columna in booleanColumns:
self.booleanSet.add(columna)

def flags(self, index):
if not index.isValid():
return Qt.ItemIsEnabled

if index.column() in self.booleanSet:
return Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsEnabled
else:
return QSortFilterProxyModel.flags(self, index)

def data(self, index, role):
if not index.isValid():
return self.nullVariant()

if index.column() in self.booleanSet and role in (Qt.CheckStateRole, Qt.DisplayRole):
if role == Qt.CheckStateRole:
value = QVariant(Qt.Checked) if index.data(Qt.EditRole).toBool() else QVariant(Qt.Unchecked)
return value
else: #if role == Qt.DisplayRole:
return self.nullVariant
else:
return QSortFilterProxyModel.data(self, index, role)

def setData(self, index, data, role):
if not index.isValid():
return False

if index.column() in self.booleanSet and role == Qt.CheckStateRole:
value = QVariant(True) if data.toInt()[0] == Qt.Checked else QVariant(False)
return QSortFilterProxyModel.setData(self, index, value, Qt.EditRole)
else:
return QSortFilterProxyModel.setData(self, index, data, role)

rosenth
27th August 2010, 17:33
in C++ syntax:
genericsortproxymodel.h content:


#ifndef GENERICSORTPROXYMODEL_H
#define GENERICSORTPROXYMODEL_H

#include <QSortFilterProxyModel>

class GenericSortProxyModel : public QSortFilterProxyModel
{
public:
GenericSortProxyModel(QObject *parent=0);
void setparametros(QList<bool> booleanColumns);
protected:
virtual Qt::ItemFlags flags ( const QModelIndex & index ) const;
virtual QVariant data ( const QModelIndex & index, int role ) const;
virtual bool setData ( const QModelIndex & index, const QVariant & value, int role );

private:
QList<bool> booleanSet;
QVariant nullVariant;

};

#endif // GENERICSORTPROXYMODEL_H


genericsortproxymodel.cpp content:


#include "genericsortproxymodel.h"

GenericSortProxyModel::GenericSortProxyModel(QObje ct *parent)
:QSortFilterProxyModel(parent)
{

}
void GenericSortProxyModel::setparametros(QList<bool> booleanColumns)
{
if(!booleanColumns.empty())
foreach(bool column , booleanColumns)
{
this->booleanSet.append(column);
}

}

Qt::ItemFlags GenericSortProxyModel::flags ( const QModelIndex & index ) const
{

if(!index.isValid())
return Qt::ItemIsEnabled;
if(booleanSet.value(index.column()))
return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
else
return QSortFilterProxyModel::flags(index);
}

QVariant GenericSortProxyModel::data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
{
if(!index.isValid())
return this->nullVariant;
if(booleanSet.value(index.column()) && (role==Qt::CheckStateRole || role==Qt::DisplayRole)) {
if(role==Qt::CheckStateRole)
return index.data(Qt::EditRole).toBool()?QVariant(Qt::Che cked):QVariant(Qt::Unchecked);
else if(role==Qt::DisplayRole)
return this->nullVariant;
}
else
return QSortFilterProxyModel::data(index,role);

}
bool GenericSortProxyModel::setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole )
{
if(!index.isValid())
return false;
if(booleanSet.value(index.column()) && role==Qt::CheckStateRole)
{
QVariant data= value.toInt()==Qt::Checked?QVariant(true):QVariant (false);
return QSortFilterProxyModel::setData(index,data,Qt::Edit Role);
}
else
return QSortFilterProxyModel::setData(index,value,role);
}



and use in main.cpp :


....
QList<bool> chkCols;
// fields that should be checkbox are 1
chkCols<<0<<0<<0<<0<<0<<0<<0<<0<<0<<1;
proxyModel->setparametros(chkCols);
proxyModel->setSourceModel(model);
ui->tableView->setModel(proxyModel);
....

rosenth
29th August 2010, 17:58
but using proxy, this code doesnt work anymore!(relations are lost) :

ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));

does anyone know solution?

villy
8th November 2010, 13:48
Sorry, i've wrong :confused: