TableView ProxyModel problem
I have a tableview controlled by a proxy. In the tableview, the highest and lowest values are highlighted through the data function in the proxy. I want the user to be able to delete a selected row (just from the view, not the source!) I have one method almost figured out. The problem is that when a row is deleted, the correct data is not highlighted. I think I need to use mapToSource and mapFromSource, but I haven't been able to get it to work properly.
This is the method I use...when the user deletes a row, the row is hidden in the tableView, then when the tableview is iterated to find the highest and lowest numbers, the hidden row is skipped. Then the identified rows are sent to the proxy to highlight the correct cells.
Is this the correct way or is there a better way? How do I get this to work?
Here is the code for the tableView creation:
testclass.cpp
Code:
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");
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::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++)
{
if (ui->printView->isRowHidden(r)) //Test if user deleted row
continue;
//QModelIndex sourceIndex=mapToSource(proxy->index(r,2));
//QModelIndex sourceIndex2=mapToSource(proxy->index(r,3));
//the above 2 lines gives a "mapToSource not declared" error
// #include <QModelIndex> is declared
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();
}
myproxymodel.cpp
Code:
#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;
}
Re: TableView ProxyModel problem
I don't understand. Do you have two views? One view where the user hides a row and another that shows the highlighted cells. If so you need to hide the row in the view that displays the proxy also.
Maybe something like this in your slot where you hide the row would work:
Code:
QModelIndexList list = view->selectionModel()->selectedRows();
view1->hideRow(index.row()); // view that displays the orgininal data
view2->hideRow(proxy->mapFromSource(queryModel->index(index.row(),0)).row()); // view displaying proxy model
}
highlightCells();
Or is the user hiding rows in the view showing the proxy?
Re: TableView ProxyModel problem
There is only one view. The highest and lowest value in a column is highlighted in the view. I want the user to be able to remove a row from the view (without removing it from the source) The problem isn't in hiding the row, it is in highlighting the correct row AFTER a row is hidden.
I forgot to show the code for hiding the row;
Code:
void DlgPrintPreview::on_btnDeleteRow_clicked()
{
if (!index.isValid())
return;
ui->printView->setRowHidden(index.row(),true);
highlightCells();
}
1 Attachment(s)
Re: TableView ProxyModel problem
What confused me was this in updateTimeStats():
Code:
if (ui->printView->isRowHidden(r)) //Test if user deleted row
While in createTimerTable() you have:
Code:
ui->tableView->setModel(proxy);
Edit: Attached is a simple app based on one of your earlier (April, I think) posts that demonstrates that what you are trying to do should work.
Re: TableView ProxyModel problem
The code you posted did not work properly :( If you hide the rows in different orders you get varied results from nothing being highlighted to one item not being highlighted until you click on the table. I think this is close. I have to go to work. I will look closer at your code to see if I can figure out why it isn't working quite right...at least when it is highlighting, it is highlighting the correct number!
Re: TableView ProxyModel problem
On my Linux box the only problem that I experienced was sometimes the highlight didn't show up until the mouse was over the view. Works well otherwise.
See if this fixes things. Add this statement to the MainWindow constructor:and add an update at the end of the slot:
Code:
void MainWindow::pbClicked(){
QModelIndexList list = ui->tableView->selectionModel()->selectedRows();
ui->tableView->hideRow(index.row());
}
highlightCells();
ui->tableView->update();
}
Edit: Oops. I see what you mean. It doesn't work if the view is sorted by a different column
1 Attachment(s)
Re: TableView ProxyModel problem
I think adding the following statement to the MainWindow ctor and making highlightCells() a slot makes it work properly. The row numbers change on a sort (duh) and need to be rehighlighted.
Code:
connect(ui->tableView->horizontalHeader(),SIGNAL(sectionClicked(int)),this,SLOT(highlightCells()));
Re: TableView ProxyModel problem
Thanks....I will try it when I get back home this afternoon!
Re: TableView ProxyModel problem
It is still not always highlighting the cells after rows are hidden. I tried a couple different things for ui->tableview but I am not sure why sometimes it doesn't work. I will look at it some more tonight.
Re: TableView ProxyModel problem
Maybe this will solve it:
Code:
void MainWindow::pbClicked(){
QModelIndexList list = ui->tableView->selectionModel()->selectedRows();
ui->tableView->hideRow(index.row());
}
highlightCells();
// ui->tableView->update();
ui->tableView->setFocus(); // add this
}
Re: TableView ProxyModel problem
That looks like it works!!! I didn't think about setting the focus....Not sure why it needed that but it works. Now to get it to work in my code!
Thanks a million!
Re: TableView ProxyModel problem
Works great! I had to modify it a bit for my application, but you got me in the right direction!!! Many thanks!!!