data, model and tree view
Hi,
I have a maybe stupid question but, can anyone help me here:
I have a data class which gets manipulated through a tableWidget. Then I have a model and a treeview based on that data. The data can only be viewed in the tree view. How do I tell the model that the data was changed through the table widget?
The table widget looks like that:
a1 1 2 3
b1 4 5
The tree view displays the full factorial combinations of a1 b1
Code:
a1
1
b1
4
5
2
b1
4
5
3
b1
4
5
So, adding a value to b1 would change the tree. I guess (at least I don't see how) I can't have a single model for the two different views since the setData is different for both views.
I appreciate any comments to help me solve my problem.
Thanks.
Re: data, model and tree view
Why do you say that you need two different models? If you insist on that (I don't say you shouldn't), use a proxy model (subclass either the abstract proxy model class or its sort/filter subclass) and implement those "versions" there using a common base. Thanks to that all three or two models (core+two proxies or core+one proxy) will always be in sync on their own.
Re: data, model and tree view
I was thinking to use two models since the two data representations have not nuch in comon.
The
a1 1 2 3
b1 4 5
is just the summary of the factors used in the full factorial representation so, it would be natural to keep them seperate. If I choose your way of having a single model and two proxies I'm struggling to find a nice interface to serve both views. Also it's not clear to me how to use the proxies since the documentation is not very good. Any suggestion where to finde more detailed info's on proxy and mybe some examples.
Thanks a lot.
Re: data, model and tree view
IMO the model is the same in both cases, just the hierarchy differs, that's why I suggest to use a proxy -- to change the hierarchy. You might want to take a look at the source of QSortFilterProxyModel. In general you need to reimplement methods responsible for mapping indexes from the source model to the proxy model and vice versa.
Re: data, model and tree view
I mananged to create a proxy model which is currently just doing the same as the model itself.
treeview
|
proxy tableview
| |
model
|
data
Playing with it I noticed that if I change data in the tablview the treeview is not updated. Do I miss something here?
Thanks.
Re: data, model and tree view
Can we see some code? Hard to say anything without it.
Re: data, model and tree view
Sure, I attached the proxyFilter code. What's also interessting that if I click into the treeview I get a bunch of cout's from the setData instead just a single one.
Code:
snip main.cpp
TestModel model;
table->setModel(&model);
ProxyFilter filterModel;
filterModel.setSourceModel(&model);
tree->setModel(&filterModel);
splitter->setWindowTitle("Test views");
splitter->show();
return app.exec();
}
proxyFilter.cpp:
Code:
#include "proxyFilter.h"
#include <iostream>
ProxyFilter::ProxyFilter() {
}
ProxyFilter::~ProxyFilter() {
}
std::cout << "mapFromSource" << std::endl;
if(sourceIndex.isValid())
return createIndex(sourceIndex.row(), sourceIndex.column());
else
}
std::cout << "mapToSource" << std::endl;
return sourceModel()->index(proxyIndex.row(), proxyIndex.column());
}
int ProxyFilter
::columnCount(const QModelIndex & parent
) const {
// return sourceModel()->columnCount(parent);
// filter out all cols - keep only col = 0
return 1;
}
int ProxyFilter
::rowCount(const QModelIndex & parent
) const { return sourceModel()->rowCount(parent);
}
QModelIndex ProxyFilter
::index(int row,
int column,
const QModelIndex
& parent
) const {
return sourceModel()->index(row, column, parent);
}
QModelIndex ProxyFilter
::parent(const QModelIndex
&) const {
}
std::cout << "data: row =" << index.row() << " col=" << index.column() << std::endl;
return sourceModel()->data(index, role);
}
std::cout << "setData: row =" << index.row() << " col=" << index.column() << std::endl;
return sourceModel()->setData(index, value, role);
}
Qt
::ItemFlags ProxyFilter
::flags(const QModelIndex &index
) const {
return sourceModel()->flags(index);
}
connect(sourceModel, SIGNAL(modelReset()), this, SIGNAL(modelReset()));
}
proxyFilter.h:
Code:
#ifndef PROXYFILTER_H
#define PROXYFILTER_H
#include <QAbstractProxyModel>
#include <QAbstractItemModel>
Q_OBJECT
public:
ProxyFilter();
~ProxyFilter();
};
#endif
Re: data, model and tree view
Well, it's actually data cout's I get when just moving the mouse over the field - strange?!?
Re: data, model and tree view
No, it's not strange :) Anyway, everytime you use indexes with the source model, you have to map them to the source model space using mapToSource(). And everytime where you get an index from the source model, you should map it to the proxy model space using mapFromSource.
As for multple occurences of data() calls -- don't worry about it, it's perfectly normal. The view is asking the model for things like a tooltip for the item under the pointer. If you extend your cout to also show the roles in question, you'll see that for yourself.
Re: data, model and tree view
You mean instead of using (e.g. in data)
return sourceModel()->data(index, role);
I should better use
return sourceModel()->data(mapToSource(index), role);
That make the code cleaner ;)
Re: data, model and tree view
Quote:
Originally Posted by larry104
You mean instead of using (e.g. in data)
return sourceModel()->data(index, role);
I should better use
return sourceModel()->data(mapToSource(index), role);
Yes. And the same in all other places. Remember that indexes are only valid in context of a current model. You can't "share" or "move" indexes between models. And you can't store them too (you have QPersistentModelIndex for that).
Re: data, model and tree view
Ok. I still have the problem that the data changed in the table is not updated in the tree view. If I click into the tree it will get of cause updated since it get's it from the model. Any idea why the views are not in sync? I should mention that if the data is changed in the treeview is updated in the tableview.
Re: data, model and tree view
I found a solution to the problem I have. I needed to connect the SIGNAL form the model to a custom slot of my PROXY which then emits a dataChanged. So, the modified setSourceModel looks like:
Code:
connect(sourceModel, SIGNAL(modelReset()), this, SIGNAL(modelReset()));
if (sourceModel) {
}
}
and the implementation of the SLOT _my_sourceDataChanged
Code:
QModelIndex proxy_top_left
= mapFromSource
(source_top_left
);
QModelIndex proxy_bottom_right
= mapFromSource
(source_bottom_right
);
emit dataChanged(proxy_top_left, proxy_bottom_right);
}
Was this really necesarry to do? Shouldn't it be the idea of a proxy to exactly do this automatically? Any comments - did I miss something?
Thanks.
Re: data, model and tree view
Yes, it should handle it on its own. It might be a bug. Are you using an up to date release of Qt?
Re: data, model and tree view
Yep, I'm using 4.1.3. Has anyone else noticed that problem?
Re: data, model and tree view
4.1.4 is the newest one. Maybe the bug has been reported? Have you checked the task-tracker on the Trolltech site?
Re: data, model and tree view
I installed 4.1.4 - same problem.
Re: data, model and tree view
I noticed the same problem as well. No signals are propagated when deriving from a QAbstractProxyModel. QSortFilterProxyModel propagates signals just fine.