QSortFilterProxyModel subclass for readonly columns columns with checkboxes and password columns: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
AutoSpider (talk | contribs) (Remove non-functioning "toc" command) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{Cleanup | reason=Auto-imported from ExpressionEngine.}} | |||
[[Category:Snippets]] | [[Category:Snippets]] | ||
= QSortFilterProxyModel subclass for readonly, checkboxes and password columns = | = QSortFilterProxyModel subclass for readonly, checkboxes and password columns = | ||
Line 64: | Line 65: | ||
void setNullAndNotNullColumns(QList<int> nullCols, QList<int> notNullCols); | void setNullAndNotNullColumns(QList<int> nullCols, QList<int> notNullCols); | ||
QVariant data(const QModelIndex & | QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const; | ||
bool setData(const QModelIndex & | bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole); | ||
Qt::ItemFlags flags ( const QModelIndex & | Qt::ItemFlags flags ( const QModelIndex & index ) const; | ||
protected: | protected: | ||
bool filterAcceptsRow ( int source_row, const QModelIndex & | bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const; | ||
signals: | signals: | ||
Line 127: | Line 128: | ||
} | } | ||
bool CheckableSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & | bool CheckableSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const { | ||
Q_UNUSED(source_parent); | Q_UNUSED(source_parent); | ||
if (!notNullSet.isEmpty()) { | if (!notNullSet.isEmpty()) { | ||
Line 135: | Line 136: | ||
return false; | return false; | ||
bool CheckableSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & | bool CheckableSortFilterProxyModel::filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const { | ||
Q_UNUSED(source_parent); | Q_UNUSED(source_parent); | ||
Line 154: | Line 155: | ||
} | } | ||
QVariant CheckableSortFilterProxyModel::data(const QModelIndex & | QVariant CheckableSortFilterProxyModel::data(const QModelIndex &index, int role) const { | ||
if (!index.isValid()) | if (!index.isValid()) | ||
return QVariant(); | return QVariant(); | ||
if (booleanSet.contains(index.column()) & | if (booleanSet.contains(index.column()) && (role Qt::CheckStateRole || role Qt::DisplayRole)) { | ||
if (role Qt::CheckStateRole) | if (role Qt::CheckStateRole) | ||
return index.data(Qt::EditRole).toBool() ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked); | return index.data(Qt::EditRole).toBool() ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked); | ||
else if (role Qt::DisplayRole) | else if (role Qt::DisplayRole) | ||
return QVariant(); | return QVariant(); | ||
} else if (passwordSet.contains(index.column()) & | } else if (passwordSet.contains(index.column()) && (role == Qt::DisplayRole)) { | ||
return QVariant("''''''*"); | return QVariant("''''''*"); | ||
} else | } else | ||
Line 171: | Line 172: | ||
} | } | ||
bool CheckableSortFilterProxyModel::setData(const QModelIndex & | bool CheckableSortFilterProxyModel::setData(const QModelIndex &index, const QVariant &value, int role) { | ||
if(!index.isValid()) | if(!index.isValid()) | ||
return false; | return false; | ||
if(booleanSet.contains(index.column()) & | if(booleanSet.contains(index.column()) && roleQt::CheckStateRole) | ||
{ | { | ||
QVariant data = (value.toInt()Qt::Checked) ? QVariant(1) : QVariant (0); | QVariant data = (value.toInt()Qt::Checked) ? QVariant(1) : QVariant (0); | ||
Line 185: | Line 186: | ||
} | } | ||
Qt::ItemFlags CheckableSortFilterProxyModel::flags ( const QModelIndex & | Qt::ItemFlags CheckableSortFilterProxyModel::flags ( const QModelIndex & index ) const { | ||
if(!index.isValid()) | if(!index.isValid()) | ||
return Qt::ItemIsEnabled; | return Qt::ItemIsEnabled; |
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);
}