I have a QTableView which is populated using a QSqlTableModel.
In this table I need to be able to set the background color (let's say yellow) of some rows (using mouse clicks) in order to do some post-processing on these "yellow-selected" rows.
I found a solution that will seem kinda cumbersome... i.e. I used a proxy model and I used the Qt::Background role to give the row(s) the desired background color (yellow if "selected" and white if not).
It works acceptably (I've noticed some delays - no big deal), yet there is a problem with my implementation: when I sort the table (clicking on some column header), the "yellow-selected" rows DO NOT change their positions according to sorting operation!... The yellow rows just keep the initial positions...
So, is there a way to do this in a simple manner? Maybe using proxy model was not the best approach?!? How / What can I do to have it respond correctly to sorting operation?
I am novice so please it would be great if you can provide some code also, as I am the kind of person who learns better from examples :)
I did try 2-3 days to fix this problem but I didn't manage to do it. Internet / googling for help was of no help so far, unfortunately.
I am using Qt 5 under Windows 7.
#include "keylistgenerator.h"
#include "ui_keylistgenerator.h"
#include "dataBase/database.h"
KeyListGenerator::KeyListGenerator(QWidget * parent) :
QDialog(parent),
ui(new Ui::KeyListGenerator)
{
ui->setupUi(this);
dbConnection = DataBase::instance()->openDataBaseConnection();
model = new QSqlTableModel(this, QSqlDatabase::database(dbConnection));
proxy = new ProxyModel(this);
// unleash the power of proxy :)
proxy->setSourceModel(model);
model->setTable("MachineStatus");
model->select();
// display
ui->tableView->setModel(proxy);
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tableView->setSelectionMode(QAbstractItemView::NoSelection);
connect(ui->tableView, SIGNAL(clicked(QModelIndex)), this, SLOT(toggleSelectCurrentRow(QModelIndex)));
connect(ui->selectAllKeys, SIGNAL(clicked()), this, SLOT(setUpdateAllKeys()));
connect(ui->cancelAllKeys, SIGNAL(clicked()), this, SLOT(cancelUpdateAllKeys()));
}
KeyListGenerator::~KeyListGenerator()
{
delete ui;
}
void KeyListGenerator::toggleSelectCurrentRow(QModelIndex index)
{
proxy->toggleRowSelection(index.row());
}
void KeyListGenerator::generateKeysListFile()
{
// TODO...
}
void KeyListGenerator::setUpdateAllKeys()
{
for(int i = 0; i < proxy->rowCount(); ++i)
{
proxy->setRowSelection(i);
}
}
void KeyListGenerator::cancelUpdateAllKeys()
{
for(int i = 0; i < proxy->rowCount(); ++i)
{
proxy->setRowSelection(i, false);
}
}
Ok, and here is my proxy model :
#include <QBrush>
#include "myproxymodel.h"
ProxyModel::ProxyModel(QObject * parent)
: QAbstractProxyModel(parent)
{
}
ProxyModel::~ProxyModel()
{
}
int ProxyModel::rowCount(const QModelIndex & parent) const
{
if(!parent.isValid())
return sourceModel()->rowCount(QModelIndex());
return 0;
}
int ProxyModel::columnCount(const QModelIndex & parent) const
{
if(!parent.isValid())
return sourceModel()->columnCount();
return 0;
}
QModelIndex ProxyModel::index(int row, int column, const QModelIndex & parent) const
{
if(!parent.isValid())
return createIndex(row, column);
return QModelIndex();
}
QModelIndex ProxyModel::parent(const QModelIndex & child) const
{
return QModelIndex();
}
QModelIndex ProxyModel::mapToSource(const QModelIndex & proxyIndex) const
{
if(!proxyIndex.isValid())
return QModelIndex();
return sourceModel()->index(proxyIndex.row(), proxyIndex.column());
}
QModelIndex ProxyModel::mapFromSource(const QModelIndex & sourceIndex) const
{
if(!sourceIndex.isValid())
return QModelIndex();
return index(sourceIndex.row(), sourceIndex.column());
}
QVariant ProxyModel::data(const QModelIndex & index, int role) const
{
if(role == Qt::BackgroundRole)
{
Qt::GlobalColor color = (map.value(index.row()) == true) ? Qt::yellow : Qt::white;
QBrush background(color);
return background;
}
return sourceModel()->data(mapToSource(index), role);
}
void ProxyModel::toggleRowSelection(int row)
{
if(row < sourceModel()->rowCount())
{
// toggle status into ProxyModel for that row
bool status = map.value(row) ^ 1;
map.insert(row, status);
QModelIndex first = createIndex(row, 0);
QModelIndex last = createIndex(row, sourceModel()->columnCount() - 1);
emit dataChanged(first, last);
}
}
void ProxyModel::setRowSelection(int row, bool selected)
{
if(row < sourceModel()->rowCount())
{
// store selected status into ProxyModel for that row
map.insert(row, selected);
QModelIndex first = createIndex(row, 0);
QModelIndex last = createIndex(row, sourceModel()->columnCount() - 1);
emit dataChanged(first, last);
}
}
And here is like it looks now...