PDA

View Full Version : Reimplemented QStandardItem



Miga
3rd April 2012, 13:14
Hello!
I've got QTreeView and QStandardItemModel. There are items in this model based on QStandardItem:

class TComplexItem : public QStandardItem
{
public:

const TElement *getElement() const;
void setElementData(const TElement & element);

private:
TElement *m_pElement; //string and integer members in class TElement
}

It's now necessary to add to the window with QTreeView some controls for representation data from m_pElement. So when we walk though the tree we should get the appropriate data for current item in these controls.
How could I do this? It looks like QDataWidgetMapper. But QDataWidgetMapper itself doesn't fit here.

Thanks in advance for any ideas.

wysota
3rd April 2012, 13:19
What's wrong with QDataWidgetMapper?

Miga
3rd April 2012, 14:09
How could I use QDataWidgetMapper in this situation?
Class TElement contains some members. And all of them belong to the same section of the model.

From the description of function QDataWidgetMapper::addMapping: "Only one-to-one mappings between sections and widgets are allowed. It is not possible to map a single section to multiple widgets..."
So, I can't use the construction like:

mapper->addMapping(nameLineEdit, 0);
Maybe, there are some other ways?

Added after 7 minutes:

Is it possible to use one QWidget as a container for all these QLineEdits and other controls?
Then

mapper->addMapping(MyWidget, 0);
But I have no idea how to put the fields to the appropriate controls (f.e. m_pElement->Name to MyWidget->leName).
appMapping is not reimplemented.

wysota
3rd April 2012, 14:12
I don't see why you'd want to map a single section to multiple widgets. As I understand TElement is some kind of structure and you want to show each field in this structure in a separate widget thus you have a perfect one to one mapping. You just have to implement the model properly which is, I guess, not what you are currently doing.

Miga
3rd April 2012, 14:25
As I understand TElement is some kind of structure and you want to show each field in this structure in a separate widget thus you have a perfect one to one mapping.
Thanks for your answers. Yes, you are quite right! But I can't catch how to do that.

You just have to implement the model properly which is, I guess, not what you are currently doing.
Sorry, I'm not quite understand. Could you say what should I reimplement in the model? I use simple QStandardItemModel now. Or you mean something other?

wysota
3rd April 2012, 14:30
The problem is not with QStandardItemModel but rather with your getElement() and setElementData() methods.

Somewhere in your code you are probably fetching standard items from the model, casting them to TComplexItem pointers and using getElement() and setElementData() to access your custom data, right? This is a bad approach, you should only be using QAbstractItemModel API for accessing the data. Since you didn't reimplement QStandardItem::data() I'm guessing you can't access fields from TElement using QAbstractItemModel::data().

I don't know what your TElement class holds, but your model should probably look like this:


class TElementModel : public QAbstractTableModel {
public:
// ...

QVariant data(const QModelIndex &index, int role == Qt::DisplayRole) const {
// check if index is valid
// ...
const TElement &item = m_data.at(index.row());
if(role == Qt::DisplayRole || role == Qt::EditRole) {
switch(index.column()) {
case 0: return item.column1;
case 1: return item.column2;
// etc.
}
}
}
private:
QList<TElement> m_data;
};

Miga
3rd April 2012, 14:48
Somewhere in your code you are probably fetching standard items from the model, casting them to TComplexItem pointers and using getElement() and setElementData() to access your custom data, right?
Yes, you are rihgt. :)

... you should only be using QAbstractItemModel API for accessing the data. Since you didn't reimplement QStandardItem::data() I'm guessing you can't access fields from TElement using QAbstractItemModel::data().

Thank you very much for your answers. I'll try to do so.