PDA

View Full Version : Selections in a TableView with a QItemSelectionModel



xelag
27th November 2006, 00:30
Hello,

I have a problem with a Model-View-Controler.

I can't get the index of the selected items in my view. It seems that there are no connection between my model and my selection model

Here is my MVC,

model : QAbstractTableModel
view : QTableView Proxy
proxy : QSortFilterProxyModel
delegate : QAbstractItemDelegate
selection model : QItemSelectionModel


My view selection setting is set as :

setSelectionMode (QAbstractItemView::ExtendedSelection);
setSelectionBehavior (QAbstractItemView::SelectRows);


In my model, each data gets a Qt::ItemFlags as Qt::ItemIsSelectable :

Qt::ItemFlags DSTableModel::flags(const QModelIndex &_index) const
{
if (!_index.isValid())
{
return QAbstractItemModel::flags(_index) | Qt::ItemIsEnabled;
}
return QAbstractItemModel::flags(_index) | Qt::ItemIsEditable | Qt::ItemIsSelectable;
}

In my main program, i use this slot function to delete the selected rows in the view:

void DSMainWindow::deleteDataSlot()
{
//Get the QModelIndex list of items selected in the view
QModelIndexList tmpModelIndexList = selectionModel->selectedIndexes();

if(tmpModelIndexList.count()==0)
{
//---> Always comes here because no items have been detected selected, despite
//the fact that the user has selected rows for real in the view !!!!!!!!!!!!!!!!!!
QMessageBox::information(this, tr("DataSearch delete data"),
tr("No data is selected"),
QMessageBox::Ok,0,0);
return;
}
else{}

int tmpMsgRet = QMessageBox::question(this, tr("DataSearch delete data"),
tr("Are you sure you want to delete the selected data?") +
tr("\nThe data deleted will be lost."),
QMessageBox::Yes,QMessageBox::No | QMessageBox::Default,0);

if (tmpMsgRet == QMessageBox::Yes)
{
//list used to store the row already deleted (multiple QModelIndex for a row
QList<int> tmpRowRemoved;

int currentRow;


for(int i=0; i<tmpModelIndexList.count();i++)
{
currentRow = tmpModelIndexList.at(i).row();

//test if the row has not been deleted yet
if(tmpRowRemoved.indexOf(currentRow) > 0)
{
//delete the row in the model
tableModel->removeRows(currentRow,1,tableView->currentIndex());
tmpRowRemoved.append(currentRow);
}
}
}
else{}
}

Can the delegate or the proxy cause a problem? Is there something to add in the model?

Please help. I'm searching for a long time where it bugs... But those MVCs are quite tough to debug...

Thx,
Xelag

wysota
27th November 2006, 00:39
Why does the "selectionModel" variable hold? How and when did you initialise it?

xelag
27th November 2006, 07:42
I don't understand your 1st question?

Why does the "selectionModel" variable hold? How and when did you initialise it?

2nd question :

How and when did you initialise it?
I initialise it in the main program :


int main(int argc, char *argv[])
{
DSTableModel *tableModel = new DSTableModel();
DSSortFilterProxy *sortFilterProxy = new DSSortFilterProxy();
DSTableView *tableView = new DSTableView(0);
DSTableDelegate *tableDelegate = new DSTableDelegate();
//here
QItemSelectionModel *selectionModel = new QItemSelectionModel(tableModel);

//After that, I create my main window; I pass through the constructor the different adress
//of MVC elements :
DSMainWindow *mainWin = new DSMainWindow(tableModel,
sortFilterProxy,
tableView,
tableDelegate,
selectionModel);
}


In the main window, each MVC element is a property class initialise in constructor with arguments writtent above.

DSMainWindow::DSMainWindow(DSTableModel *_tableModel,
DSSortFilterProxy *_sortFilterProxy,
DSTableView * _tableView,
DSTableDelegate *_tableDelegate,
QItemSelectionModel *_selectionModel,
QWidget *parent,
Qt::WFlags flags)
: QMainWindow(parent, flags)
{
//Initialisation of properties
tableModel = _tableModel;;
sortFilterProxy = _sortFilterProxy;
tableView = _tableView;
tableDelegate = _tableDelegate;
selectionModel = _selectionModel;

//Initialisation of the model structure
sortFilterProxy->setSourceModel(tableModel);
tableView->setModel(sortFilterProxy);
tableView->setItemDelegate(tableDelegate);
tableView->setSelectionModel(selectionModel);
//...

wysota
27th November 2006, 09:45
I don't understand your 1st question?
Sorry, should be "what" instead of "why" :)



2nd question :

I initialise it in the main program :


int main(int argc, char *argv[])
{
// ...
DSTableView *tableView = new DSTableView(0);
// ...
QItemSelectionModel *selectionModel = new QItemSelectionModel(tableModel);




//Initialisation of the model structure
sortFilterProxy->setSourceModel(tableModel);
tableView->setModel(sortFilterProxy);
//...
tableView->setSelectionModel(selectionModel);
//...

How about:

QTableView *view = new QTableView(...);
tableView->setModel(sortFilterProxy);
QItemSelectionModel = tableView->selectionModel(); // <-- use this one

You don't need to create your own selection model, the view already has one. The selection model will tell you about selections of the model which is set in the view - in your case the proxy model, so you need to map indexes to the source model using QAbstractProxyModel::mapToSource() if you want to operate on the model directly. But it is possible that you can do most operations by operating on the proxy instead - then you don't need to map indexes.