I have a program that uses several tables and I highlight certain cells in the tableView. I have a proxyModel to make this happen. I use almost identical code for several different tables but on one tableView it isn’t showing correctly. The first thing I notice is that the table is shown in reverse order. In other words, the table shows the last item from the database first. All the other tableViews I use, show the data in a first to last order. The other problem is that the correct data is not highlighted. If the table was in the correct order, the correct cell would be highlighted. I think my problem might be with a mapToSource issue but I don’t know what index to use?? (I am a Newbie to Qt and trying to learn) I do not know why the table is shown in reverse order? Also, what events trigger the setData() function?
Here is the code I have for the proxy model:
myproxymodel.h
#ifndef MYPROXYMODEL_H
#define MYPROXYMODEL_H
#include <QSortFilterProxyModel>
{
Q_OBJECT
public:
~MyProxyModel();
private:
int m_lowScore;
int m_highScore;
int m_lowReactRow;
int m_fastReactRow;
MyProxyModel* proxy;
private slots:
void getRows (int, int, int, int);
};
#endif //MYPROXYMODEL_H
#ifndef MYPROXYMODEL_H
#define MYPROXYMODEL_H
#include <QSortFilterProxyModel>
class MyProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
MyProxyModel(QObject* parent);
~MyProxyModel();
QVariant data ( const QModelIndex & index, int role )const;
private:
int m_lowScore;
int m_highScore;
int m_lowReactRow;
int m_fastReactRow;
MyProxyModel* proxy;
private slots:
void getRows (int, int, int, int);
};
#endif //MYPROXYMODEL_H
To copy to clipboard, switch view to plain text mode
myproxymodel.cpp
#include "myproxymodel.h"
MyProxyModel
::MyProxyModel (QObject *parent
) :{
}
MyProxyModel::~MyProxyModel()
{
}
{
if (!sourceIndex.isValid())
if (m_slowReactRow<0)
{
if ( sourceIndex.row() == m_highScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
}
else if ( sourceIndex.row() == m_lowScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
}
else
{
}
}
else
{
if ( sourceIndex.row() == m_highScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
}
else if ( sourceIndex.row() == m_lowScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
}
else if (sourceIndex.row()== m_fastReactRow && sourceIndex.column()==3 && role == Qt::BackgroundRole)
{
}
else if ( sourceIndex.row() == m_slowReactRow && sourceIndex.column()== 3 && role == Qt::BackgroundRole )
{
}
else
{
}
}
}
void MyProxyModel::getRows( int rowLow,int rowHigh, int rowSlowReact, int rowFastReact)
{
m_highScore=rowHigh;
m_lowScore=rowLow;
m_slowReactRow= rowSlowReact;
m_fastReactRow= rowFastReact;
}
#include "myproxymodel.h"
MyProxyModel::MyProxyModel (QObject *parent) :
QSortFilterProxyModel(parent)
{
}
MyProxyModel::~MyProxyModel()
{
}
QVariant MyProxyModel::data ( const QModelIndex & index, int role ) const
{
QModelIndex sourceIndex = mapToSource(index);
if (!sourceIndex.isValid())
return QVariant();
if (m_slowReactRow<0)
{
if ( sourceIndex.row() == m_highScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
return QVariant( Qt::yellow );
}
else if ( sourceIndex.row() == m_lowScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
return QVariant( Qt::red );
}
else
{
return QSortFilterProxyModel::data( index, role );
}
}
else
{
if ( sourceIndex.row() == m_highScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
return QVariant( Qt::yellow );
}
else if ( sourceIndex.row() == m_lowScore && sourceIndex.column()== 2 && role == Qt::BackgroundRole )
{
return QVariant( Qt::red );
}
else if (sourceIndex.row()== m_fastReactRow && sourceIndex.column()==3 && role == Qt::BackgroundRole)
{
return QVariant( Qt::yellow );
}
else if ( sourceIndex.row() == m_slowReactRow && sourceIndex.column()== 3 && role == Qt::BackgroundRole )
{
return QVariant( Qt::red );
}
else
{
return QSortFilterProxyModel::data( index, role );
}
}
}
void MyProxyModel::getRows( int rowLow,int rowHigh, int rowSlowReact, int rowFastReact)
{
m_highScore=rowHigh;
m_lowScore=rowLow;
m_slowReactRow= rowSlowReact;
m_fastReactRow= rowFastReact;
}
To copy to clipboard, switch view to plain text mode
This is the table creation code for one of the tableViews that show correctly:
testclass.cpp
void TestClass::createTimerTable() // this is called in the constructor of the form
{
testModel->setTable("testtable");
testModel
->setRelation
(2,
QSqlRelation("student",
"id",
"LName"));
testModel
->setRelation
(3,
QSqlRelation("testNum",
"id",
"Test"));
testModel->setHeaderData(1,Qt::Horizontal,"Section");
testModel->select();
proxy = new MyProxyModel (this);
proxy->setSourceModel(testModel);
ui->tableView->setModel(proxy);
connect(this,SIGNAL(sendRows(int, int, int, int)),
proxy, SLOT(getRows(int, int, int, int)));
//set up tableview
ui->tableView->setColumnHidden(0,true); // id
ui->tableView->resizeColumnsToContents();
ui->tableView->horizontalHeader()->setStretchLastSection(true);
}
void TestClass
::setTable(QString desc
) //This is called in the constructor after createTimerTable {
mTableString=desc;
testModel
->setFilter
(QString(desc
));
testModel->select();
updateTimeStats();
}
void TestClass::updateTimeStats()
{
float totScore=0;
float totReactTime=0;
float lowScore=FLT_MAX;
int rowLowScore=0;
int rowHighScore =0;
int rowSlowReact =0;
int rowFastReact =0;
float slowReactTime =FLT_MIN;
float highScore=FLT_MIN;
float fastReactTime=FLT_MAX;
float currentScore=0;
float currentReactTime =0;
int totRows=proxy->rowCount();
if (totRows >0)
{
for (int r=0; r<totRows; r++)
{
currentScore=proxy->index(r,2).data(Qt::DisplayRole).toFloat();
currentReactTime=proxy->index(r,3).data(Qt::DisplayRole).toFloat();
if (currentScore < lowScore)
{
lowScore=currentScore;
rowLowScore=r;
}
if (currentScore > highScore)
{
highScore=currentScore;
rowHighScore =r;
}
if (currentReactTime > slowReactTime)
{
slowReactTime=currentReactTime;
rowSlowReact =r;
}
if (currentReactTime<fastReactTime)
{
fastReactTime=currentReactTime;
rowFastReact =r;
}
totTime+=currentTime;
totReactTime+=currentReactTime;
}
startModel->select();
}
void TestClass::createTimerTable() // this is called in the constructor of the form
{
testModel= new QSqlRelationalTableModel(this);
testModel->setEditStrategy(QSqlTableModel::OnRowChange);
testModel->setTable("testtable");
testModel->setRelation(2,QSqlRelation("student","id", "LName"));
testModel->setRelation(3,QSqlRelation("testNum", "id","Test"));
testModel->setHeaderData(1,Qt::Horizontal,"Section");
testModel->select();
proxy = new MyProxyModel (this);
proxy->setSourceModel(testModel);
ui->tableView->setModel(proxy);
connect(this,SIGNAL(sendRows(int, int, int, int)),
proxy, SLOT(getRows(int, int, int, int)));
//set up tableview
ui->tableView->setItemDelegate(new QSqlRelationalDelegate(this));
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setColumnHidden(0,true); // id
ui->tableView->resizeColumnsToContents();
ui->tableView->horizontalHeader()->setStretchLastSection(true);
}
void TestClass::setTable(QString desc) //This is called in the constructor after createTimerTable
{
mTableString=desc;
testModel->setFilter(QString(desc));
testModel->select();
updateTimeStats();
}
void TestClass::updateTimeStats()
{
float totScore=0;
float totReactTime=0;
float lowScore=FLT_MAX;
int rowLowScore=0;
int rowHighScore =0;
int rowSlowReact =0;
int rowFastReact =0;
float slowReactTime =FLT_MIN;
float highScore=FLT_MIN;
float fastReactTime=FLT_MAX;
float currentScore=0;
float currentReactTime =0;
QString string;
int totRows=proxy->rowCount();
if (totRows >0)
{
for (int r=0; r<totRows; r++)
{
currentScore=proxy->index(r,2).data(Qt::DisplayRole).toFloat();
currentReactTime=proxy->index(r,3).data(Qt::DisplayRole).toFloat();
if (currentScore < lowScore)
{
lowScore=currentScore;
rowLowScore=r;
}
if (currentScore > highScore)
{
highScore=currentScore;
rowHighScore =r;
}
if (currentReactTime > slowReactTime)
{
slowReactTime=currentReactTime;
rowSlowReact =r;
}
if (currentReactTime<fastReactTime)
{
fastReactTime=currentReactTime;
rowFastReact =r;
}
totTime+=currentTime;
totReactTime+=currentReactTime;
}
startModel->select();
}
To copy to clipboard, switch view to plain text mode
Here is the code for the tableView that is in reverse order and not highlighted correctly:
dlgprint.cpp
void DlgPrint
::createReportTable(QStringList stringList
) //strinLlist is used elsewhere {
printModel-> setTable (mTableName); //string identified through assessor function
printModel
-> setRelation
(2,
QSqlRelation("student",
"id",
"LName"));
printModel
-> setRelation
(3,
QSqlRelation("testNum",
"id",
"Test"));
printModel->setFilter(mFilterString);
printModel->select();
proxy = new MyProxyModel(this);
proxy->setSourceModel(printModel);
ui->printView->setModel(proxy);
connect(this,SIGNAL(sendRows(int, int, int, int)),
proxy, SLOT(getRows(int, int, int, int)));
ui->printView->setColumnHidden(0,true);//id
ui->printView->resizeColumnsToContents();
printModel->setHeaderData (2, Qt::Horizontal, "Score");
ui->printView->setSortingEnabled(true);
ui->printView->resizeColumnsToContents () ;
ui->printView->horizontalHeader()->setStretchLastSection(true);
highlightCells();
printModel->select();
}
void DlgPrint::highlightCells()
{
float highScore= FLT_MIN;
float lowScore= FLT_MAX;
float fastReactionTime=FLT_MAX;
float slowReactionTime=FLT_MIN;
int rowHigh=0;
int rowLow=0;
int rowFastReact=0;
int rowSlowReact=0;
float totalTime =0;
float totalReactTime=0;
float averageScore =0;
float averageReact=0;
int totalRows = 0;
float currentScore;
float currentReactTime;
int numRows =proxy->rowCount();
for (int r=0; r<numRows; r++ )
{
currentscore = proxy->index(r,2).data(Qt::DisplayRole).toFloat();
currentReactTime = proxy->index(r,3).data(Qt::DisplayRole).toFloat();
//something here to mapToSource??
if (currentScore > highScore)
{
highScore = currentScore;
rowHigh = r;
}
if (currentScore < lowScore)
{
lowScore = currentScore;
rowLow = r;
}
totalRows++;
totalScore += currentScore;
if (currentReactTime < fastReactionTime)
{
fastReactionTime = currentReactTime;
rowFastReact = r;
}
if (currentReactTime > slowReactionTime)
{
slowReactionTime = currentReactTime;
rowSlowReact = r;
}
totalReactTime += currentReactTime;
}
}
if (totalRows !=0)
{
averageScore=totalScore/totalRows;
averageReact=totalReactTime/totalRows;
}
emit sendRows (rowSlow, rowFast,rowSlowReact, rowFastReact);
}
void DlgPrint::createReportTable(QStringList stringList) //strinLlist is used elsewhere
{
printModel= new QSqlRelationalTableModel (this);
printModel-> setEditStrategy(QSqlTableModel::OnManualSubmit);
printModel-> setTable (mTableName); //string identified through assessor function
printModel-> setRelation (2, QSqlRelation("student", "id", "LName"));
printModel-> setRelation (3, QSqlRelation("testNum", "id", "Test"));
printModel->setFilter(mFilterString);
printModel->select();
proxy = new MyProxyModel(this);
proxy->setSourceModel(printModel);
ui->printView->setModel(proxy);
connect(this,SIGNAL(sendRows(int, int, int, int)),
proxy, SLOT(getRows(int, int, int, int)));
ui->printView->setItemDelegate(new QSqlRelationalDelegate(this));
ui->printView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->printView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->printView->setColumnHidden(0,true);//id
ui->printView->resizeColumnsToContents();
printModel->setHeaderData (2, Qt::Horizontal, "Score");
ui->printView->setSortingEnabled(true);
ui->printView->resizeColumnsToContents () ;
ui->printView->horizontalHeader()->setStretchLastSection(true);
highlightCells();
printModel->select();
}
void DlgPrint::highlightCells()
{
float highScore= FLT_MIN;
float lowScore= FLT_MAX;
float fastReactionTime=FLT_MAX;
float slowReactionTime=FLT_MIN;
int rowHigh=0;
int rowLow=0;
int rowFastReact=0;
int rowSlowReact=0;
float totalTime =0;
float totalReactTime=0;
float averageScore =0;
float averageReact=0;
int totalRows = 0;
float currentScore;
float currentReactTime;
QString string;
int numRows =proxy->rowCount();
for (int r=0; r<numRows; r++ )
{
currentscore = proxy->index(r,2).data(Qt::DisplayRole).toFloat();
currentReactTime = proxy->index(r,3).data(Qt::DisplayRole).toFloat();
//something here to mapToSource??
if (currentScore > highScore)
{
highScore = currentScore;
rowHigh = r;
}
if (currentScore < lowScore)
{
lowScore = currentScore;
rowLow = r;
}
totalRows++;
totalScore += currentScore;
if (currentReactTime < fastReactionTime)
{
fastReactionTime = currentReactTime;
rowFastReact = r;
}
if (currentReactTime > slowReactionTime)
{
slowReactionTime = currentReactTime;
rowSlowReact = r;
}
totalReactTime += currentReactTime;
}
}
if (totalRows !=0)
{
averageScore=totalScore/totalRows;
averageReact=totalReactTime/totalRows;
}
emit sendRows (rowSlow, rowFast,rowSlowReact, rowFastReact);
}
To copy to clipboard, switch view to plain text mode
I tried to eliminate the code that was irrelevant to the table creation. Hopefully I didn’t forget something. What is wrong here?
Bookmarks