Probably a newbie problem about custom tree structure and QDataWidgetMapper...
Unsolved
General and Desktop
-
Hello there,
I've built a custom tree model by inheriting QAbstractItemModel and displayed the data with a QTreeView object successfully.The problem is that when I was trying to map the data of the model to some QLineEdit objects, they didn't give me a crap (nothing showed up).
The "data" function in the tree model returns "QString".I called "setCurrentModelIndex()" of the QDataWidgetMapper to set up the model index to be that of "Gray". I expected the 3 QLineEdit objects to display "Peter", "Robert", and "Amber".
Could anyone give me a hint about what I missed?
// The mainwindow object implementation MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { manageWindow(); resize(600,400); } MainWindow::~MainWindow(){ } void MainWindow::setDataModel(){ } void MainWindow::manageWindow(){ TreeModel* model = new TreeModel; QItemSelectionModel* selection = new QItemSelectionModel; selection->setModel(model); QSplitter* splitter = new QSplitter(this); QTreeView* treeView = new QTreeView(this); //FamilyTreeDelegate *delegate = new FamilyTreeDelegate(); treeView->setModel(model); treeView->setAnimated(true); treeView->setHeaderHidden(true); //treeView->setSelectionModel(selection); DataMapperWidget* mapper = new DataMapperWidget(model); splitter->addWidget(treeView); splitter->addWidget(mapper); splitter->setSizes({150,150}); setCentralWidget(splitter); }
The implementation below is that of the widget with QDataWidgetMapper.
//The widget with the QDataWidgetMapper DataMapperWidget::DataMapperWidget(QAbstractItemModel* model, QWidget *parent) : QWidget(parent) { setWidgets(); setModel(model); } DataMapperWidget::~DataMapperWidget() { } void DataMapperWidget::setWidgets() { QFormLayout* layout = new QFormLayout; layout->setSpacing(20); layout->setContentsMargins(30,30,30,30); edit1 = new QLineEdit; edit2 = new QLineEdit; edit3 = new QLineEdit; layout->addWidget(edit1); layout->addWidget(edit2); layout->addWidget(edit3); setLayout(layout); resize(400,200); } void DataMapperWidget::setModel(QAbstractItemModel *model) { mapper = new QDataWidgetMapper(this); mapper->setOrientation(Qt::Vertical); mapper->setModel(model); QModelIndex parentIndex = model->index(0,0,QModelIndex()); mapper->setCurrentModelIndex(parentIndex); mapper->addMapping(edit1, 0); mapper->addMapping(edit2, 1); mapper->addMapping(edit3, 2); mapper->toFirst(); }
And this is the implementation of the custom tree model:
// the treemodel TreeModel::TreeModel(QObject* parent): QAbstractItemModel (parent){ Family = new FamilyMember("Family"); setModelData(); } TreeModel::~TreeModel(){ delete Family; } QVariant TreeModel::data(const QModelIndex &index, int role) const{ if (!index.isValid()) return QVariant(); if (role != Qt::DisplayRole) return QVariant(); FamilyMember* item = static_cast<FamilyMember*>(index.internalPointer()); return item->name; //QVariant v; //v.setValue(*item); //return v; } QModelIndex TreeModel::index(int row, int column, const QModelIndex& parent) const{ if (hasIndex(row, column, parent)) { if (parent.isValid()){ FamilyMember* parentItem = static_cast<FamilyMember*>(parent.internalPointer()); FamilyMember* childItem = parentItem->child(row); return createIndex(row, 0, childItem); } FamilyMember* parentItem = Family; FamilyMember* childItem = parentItem->child(row); return createIndex(row, 0, childItem); } return QModelIndex(); } int TreeModel::rowCount(const QModelIndex &parent) const{ FamilyMember* parentMember; if (!parent.isValid()) parentMember = Family; else { parentMember = static_cast<FamilyMember*>(parent.internalPointer()); } return parentMember->numberOfChildren(); } int TreeModel::columnCount(const QModelIndex &parent) const{ Q_UNUSED(parent); return 1; } QModelIndex TreeModel::parent(const QModelIndex &index) const{ if (!index.isValid()) return QModelIndex(); FamilyMember* childrenItem = static_cast<FamilyMember*>(index.internalPointer()); FamilyMember* ParentItem = childrenItem->parentItem(); if (ParentItem == Family){ return QModelIndex(); } return createIndex(ParentItem->row(), 0, ParentItem); } void TreeModel::setModelData(){ FamilyMember* grandParent = new FamilyMember("grandparent", "Gray", 98 , Family); FamilyMember* Parent = new FamilyMember("parent", "Peter", 40, grandParent); FamilyMember* uncle = new FamilyMember("uncle", "Robert", 38, grandParent); FamilyMember* aunt = new FamilyMember("aunt", "Amber", 30, grandParent); FamilyMember* son = new FamilyMember("son", "Sean", 11 ,Parent); FamilyMember* daughter = new FamilyMember("daughter", "Diana", 12 , Parent); FamilyMember* sonOfUncle = new FamilyMember("Son of uncle", "Sam", 13 ,uncle); FamilyMember* daughterOfUncle = new FamilyMember("Daughter of uncle", "Dann", 14, uncle); FamilyMember* sonOfAunt = new FamilyMember("Son of aunt", "Ethan ", 15,aunt); FamilyMember* daughterOfAunt = new FamilyMember("Daughter of aunt", "Emily" ,16, aunt); FamilyMember* daughterOfDaughterOfAunt = new FamilyMember("Daughter of daughter of aunt", "Sarah", 1, daughterOfAunt); }
This is the object definition used in the treemodel:
// Familymember class FamilyMember::FamilyMember(){} FamilyMember::FamilyMember(const QString& Appellation, const QString& Name, const int& Age, FamilyMember* parent) { appellation = Appellation; name = Name; age = Age; m_parent = parent; if (parent) { m_parent->appendChildItem(this); } } FamilyMember::FamilyMember(const FamilyMember& F) { appellation = F.appellation; name = F.name; age = F.age; m_parent = F.m_parent; } FamilyMember::~FamilyMember(){ qDeleteAll(m_children); } void FamilyMember::appendChildItem(FamilyMember* newChild){ m_children.append(newChild); } FamilyMember* FamilyMember::parentItem() const{ return m_parent; } FamilyMember* FamilyMember::child(int row){ if (row < 0 || row > m_children.count()) return nullptr; return m_children.at(row); } int FamilyMember::numberOfChildren(){ return m_children.size(); } int FamilyMember::row(){ if (parentItem()) //return parentItem()->m_children.indexOf(const_cast<FamilyMember*>(this)); // What "simpletreemodel" example does. return parentItem()->m_children.indexOf(this); // What I does. It seems that the two methods both work. return 0; }