QSortFilterProxyModel subclass for readonly columns columns with checkboxes and password columns: Difference between revisions
Jump to navigation
Jump to search
AutoSpider (talk | contribs) (Decode HTML entity names) |
AutoSpider (talk | contribs) (Remove non-functioning "toc" command) |
||
Line 2: | Line 2: | ||
[[Category:Snippets]] | [[Category:Snippets]] | ||
= QSortFilterProxyModel subclass for readonly, checkboxes and password columns = | = QSortFilterProxyModel subclass for readonly, checkboxes and password columns = |
Latest revision as of 12:28, 17 April 2015
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine. Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean. |
QSortFilterProxyModel subclass for readonly, checkboxes and password columns
When you try to use a QTableView with QSql*' model classes, it is difficult to make boolean column appear as check boxes or make columns readonly.
This is a QSortFilterProxyModel subclass that is designed to be generic enough to easily accomplish these tasks. It also includes some primitive 'password' field support.
If you want to add a check box to a model but you don't want to use a boolean field in the source model to keep track of the value of the check box, you can take a look at CheckableProxyModel.
You should create three
QList<int>
container classes, one each to hold the column indexes of the fields you want checkboxes for, to be displayed as passwords, or be readonly.
- NOTE: If you are using a QSqlRelationalTableModel, there are issues with the QSortFilterProxyModel (the combo box). To resolve that, I have created another wiki article about a QSqlRelationalDelegate subclass (mySqlRelationalDelegate) that you can use.
- EDIT: Since I discovered another problem with the handling of NULL values, I have added the possibility to this class to address it.
Usage
The subclass usage is as follows:
CheckableSortFilterProxyModel *cfpm = new CheckableSortFilterProxyModel(this);
QList<int> boolCols;
boolCols.append( usrModel->fieldIndex("isActive") );
boolCols.append( usrModel->fieldIndex("isOk") );
QList<int> readonlyCols;
readonlyCols.append( usrModel->fieldIndex("id") );
QList<int> pwdCols;
pwdCols.append( usrModel->fieldIndex("passwordFld"));
cfpm->setParameters(boolCols, readonlyCols, pwdCols);
cfpm->setSourceModel( mySqlTableModel );
myTableView->setModel(cfpm);
QList<int> nullCols;
QList<int> notNullCols;
notNullCols.append( usrModel->fieldIndex("isActive");
cfpm->setNotNullColumns(nullCols, notNullCols);
Code
So here is the code:
checkablesortfilterproxymodel.h
#ifndef CHECKABLESORTFILTERPROXYMODEL_H
#define CHECKABLESORTFILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
class CheckableSortFilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit CheckableSortFilterProxyModel(QObject *parent = 0);
void setParameters(QList<int> boolCols, QList<int> readonlyCols, QList<int> passwordCols);
void setNullAndNotNullColumns(QList<int> nullCols, QList<int> notNullCols);
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole);
Qt::ItemFlags flags ( const QModelIndex & index ) const;
protected:
bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;
signals:
public slots:
private:
QList<int> booleanSet;
QList<int> passwordSet;
QList<int> readonlySet;
QList<int> notNullSet;
QList<int> nullSet;
};
checkablesortfilterproxymodel.cpp
#include "checkablesortfilterproxymodel.h"
CheckableSortFilterProxyModel::CheckableSortFilterProxyModel(QObject *parent) :
QSortFilterProxyModel(parent)
{
}
void CheckableSortFilterProxyModel::setParameters(QList<int> boolCols, QList<int> readonlyCols, QList<int> passwordCols) {
booleanSet.clear();
readonlySet.clear();
passwordSet.clear();
if (!boolCols.isEmpty()) { foreach(int column , boolCols) { booleanSet.append(column); } }
if (!readonlyCols.isEmpty()) { foreach(int column , readonlyCols) { readonlySet.append(column); } }
if (!passwordCols.isEmpty()) { foreach(int column , passwordCols) { passwordSet.append(column); } }
}
void CheckableSortFilterProxyModel::setNullAndNotNullColumns(QList<int> nullCols, QList<int> notNullCols) {
notNullSet.clear();
nullSet.clear();
if (!notNullCols.isEmpty()) {
// this only works when our model is a QSqlQueryModel subclass
if (sourceModel()->inherits("QSqlQueryModel")) {
foreach(int column , notNullCols) { notNullSet.append(column); }
}
invalidateFilter();
}
if (!nullCols.isEmpty()) {
// this only works when our model is a QSqlQueryModel subclass
if (sourceModel()->inherits("QSqlQueryModel")) {
foreach(int column , nullCols) { nullSet.append(column); }
}
invalidateFilter();
}
}
bool CheckableSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const {
Q_UNUSED(source_parent);
if (!notNullSet.isEmpty()) {
QSqlQueryModel '''m = static_cast<QSqlQueryModel'''>(sourceModel());
foreach (int column, notNullSet)
if (m->record(source_row).isNull(column))
return false;
bool CheckableSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const {
Q_UNUSED(source_parent);
if (!notNullSet.isEmpty()) {
QSqlQueryModel '''m = static_cast<QSqlQueryModel'''>(sourceModel());
foreach (int column, notNullSet)
if (m->record(source_row).isNull(column))
return false;
}
if (!nullSet.isEmpty()) {
QSqlQueryModel '''m = static_cast<QSqlQueryModel'''>(sourceModel());
foreach (int column, nullSet)
if (!m->record(source_row).isNull(column))
return false;
}
return true;
}
QVariant CheckableSortFilterProxyModel::data(const QModelIndex &index, int role) const {
if (!index.isValid())
return QVariant();
if (booleanSet.contains(index.column()) && (role Qt::CheckStateRole || role Qt::DisplayRole)) {
if (role Qt::CheckStateRole)
return index.data(Qt::EditRole).toBool() ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
else if (role Qt::DisplayRole)
return QVariant();
} else if (passwordSet.contains(index.column()) && (role == Qt::DisplayRole)) {
return QVariant("''''''*");
} else
return QSortFilterProxyModel::data(index,role);
return QVariant();
}
bool CheckableSortFilterProxyModel::setData(const QModelIndex &index, const QVariant &value, int role) {
if(!index.isValid())
return false;
if(booleanSet.contains(index.column()) && roleQt::CheckStateRole)
{
QVariant data = (value.toInt()Qt::Checked) ? QVariant(1) : QVariant (0);
return QSortFilterProxyModel::setData(index, data, Qt::EditRole);
}
else
return QSortFilterProxyModel::setData(index,value,role);
}
Qt::ItemFlags CheckableSortFilterProxyModel::flags ( const QModelIndex & index ) const {
if(!index.isValid())
return Qt::ItemIsEnabled;
if (booleanSet.contains(index.column()))
return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
else if (readonlySet.contains(index.column()))
return Qt::ItemIsSelectable;
else
return QSortFilterProxyModel::flags(index);
}