Прошу сильно не пинать, может уже и избитый вопрос, но я в форуме не нашёл.
Если есть тема с решением, прошу ткнуть в ссыль ...
В общем траблема в выборе узла в QTreeView, из примера simpledommodel.
Добавил я в узел свой уникальный ключ Id, по которому ведётся поиск.
DomItem *DomItem::findIDD(int fIdd )
{
int i, nCnt;
DomItem *childItem;
if (fIdd == Idd) return this;
nCnt = domNode.childNodes().count();
for (i = 0;i < nCnt;i++)
{
if (childItem = child(i)->findIDD(fIdd ))
return childItem;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
Это из View
qDebug() << fitem->row();
QModelIndex index = model->index(fitem->row(), 0, QModelIndex());
scrollTo(index, EnsureVisible);
//////////////////////////////////////////////////////////////////////////////////////////////////////
В TreeModel важно правильно указать родителя, если найденный узел ниже по уровню вложенности чем корневой. QModelIndex() означает рута как родителя.
Вот здесь подробнее:
http://qt-project.org/doc/qt-4.8/model-view-programming.html#parents-of-items
do {
if (fitem)
qDebug() << fitem->node().nodeName()
<< fitem->node().toElement().attribute("name")
<< " IDD = " << fitem->Idd << "\n";
else
qDebug() << "End !";
fitem = fitem->parent();
if (fitem->Idc < 3) break; // ROOT
} while(fitem);
Если ваша модель возвращает этот id для какой нибудь роли, то можно получить готовый индекс через match:
http://qt-project.org/doc/qt-5/qabstractitemmodel.html#match
Если получится, выложите минимальный пример, попробую посмотреть что там не так.
// Это переработанный simpledommodel
class MdiChild : public QTreeView
{
Q_OBJECT
.....................
}
void MdiChild::findIDD()
{
QModelIndex index = selectedIndexes().first();
DomItem *item = static_cast<DomItem*>(index.internalPointer());
int tfIdd = QInputDialog::getInt(this, tr("Find Idd Object"), tr("Idd: "));
DomItem *fitem = item->findIDD(tfIdd);
///////////////////////////////////////////////////////////////////////////////////////////////
QModelIndex index = model->index(fitem->row(), 0, QModelIndex());
scrollTo(index, EnsureVisible);
///////////////////////////////////////////////////////////////////////////////////////////////
if (fitem)
{
do {
qDebug() << fitem->node().nodeName()
<< fitem->node().toElement().attribute(getTagByClass(201))
<< " IDC = " << fitem->Idc
<< " IDD = " << fitem->Idd;
fitem = fitem->parent();
if (fitem->Idc < 3) break;
} while(fitem);
}
}
// Это переработанный simpledommodel
class MdiChild : public QTreeView
{
Q_OBJECT
.....................
}
void MdiChild::findIDD()
{
QModelIndex index = selectedIndexes().first();
DomItem *item = static_cast<DomItem*>(index.internalPointer());
int tfIdd = QInputDialog::getInt(this, tr("Find Idd Object"), tr("Idd: "));
DomItem *fitem = item->findIDD(tfIdd);
/////////////////////////////////////////////////////////////////////////////////////////////
QModelIndex index = model->index(fitem->row(), 0, QModelIndex());
scrollTo(index, EnsureVisible);
/////////////////////////////////////////////////////////////////////////////////////////////
if (fitem)
{
do {
qDebug() << fitem->node().nodeName()
<< fitem->node().toElement().attribute("name")
<< " IDC = " << fitem->Idc
<< " IDD = " << fitem->Idd;
fitem = fitem->parent();
if (fitem->Idc < 3) break; // Root
} while(fitem);
}
}
Имеете ввиду:
treeView->selectionModel()->select(index) ?
http://qt-project.org/doc/qt-4.8/qitemselectionmodel.html#select
Спасибо за ответ. lanz извиняюсь что морочу вам ... , но не "догоняю"
Idd я вижу только когда дерево развёрнуто, как на снимке.
Поиск мне возвращает указатель на узел DomItem * (из примера QT, как писалось выше)
Видимо индекс найденного узла получаю НЕ правильный, поэтому и не позиционирует ?
QModelIndex index = model->index(fitem->row(), 0, QModelIndex());
// fitem->row() почему-то ВСЕГДА 1 Фактически вернулись к 1-й месаге темы
Тогда вопрос, - как его (QModelIndex) получить, правильный, имея указатель
на найденный объект DomItem * ???
Из объекта вообще возможно получить его индекс в модели ?
///////////////////////////////////////////////////////////////////////////////////////
QModelIndex DomModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
DomItem *parentItem;
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<DomItem*>(parent.internalPointer());
DomItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
Не стоит искать элементы так. Воспользуйтесь интерфейсом модели.
Прикрепил пример проекта. Исправьте если что не так в нем, будем над ним работать.
Не очень удобно пытаться составить в голове куски кода.
lanz - БлагоДарю ! Это действительно то, что мне нужно в проект.
Описание ф-ции match(...) для меня было не совсем понятным, (из-за индекса) поэтому "слепил" свой вариант
поиска Idd. Конечно-же "малость" придётся переделать то что уже есть, т.к. "структуры" различны (sdi<-->mdi) ...
В связИ с этим, есть несколько вопросов.
При добавлении и удалении строк у меня просто вставляется/удаляется узел в/из QDomDocument,
например для справочника
if ((item->Idc == 100)) // New Catalogue
{
newobj = model->insertCatalogue(&item->node().toElement(), text );
collapse ( index );
expand ( index ); // <-- ес-сно parent
return(newobj);
}
Обычно я не пользуюсь insert/removeRows. Как написано в документации:
void MyModel::insertElement(const QModelIndex &parent, int id)
{
Element * pEl = this->mRoot;
if( parent.isValid() ) pEl = (Element*)parent.internalPointer();
this->beginInsertRows( parent, pEl->children().size(), pEl->children().size() );
Element * el = new Element( pEl );
el->id = id;
this->endInsertRows();
}
Это я спрашивал согласно примера editabletreemodel. Там демонстрируется поддержка
вставки-удаления в модели и элементе. Поэтому, я так понял, эта поддержка нужна
будет и здесь, в Вашей модели.
lanz, а от чего зависит обновление на экране в TreeView-е ?
Дело в том, что данные в узле, обновляемые из диалога, почему-то обновляются в TreeView-е
по-разному, в зависимости от колонки. Если в 1-й, обновляются мгновенно, если в 4-й (value)
не обновляется (на экране, хотя данные в реальности обновлены). Это видно при сохранении
конфигурации. Не хватат сигнала datachanged ?!
Не хватает
Если меняете данные, нужно посылать dataChanged.
Всем Здравствовать !
Дабы не плодить "лишних" тем, продолжу здесь, тем-более что вопрос(ы) по данной теме (проекта).
В прицепе небольшой проектик, с которого я начал свой, с добавленным поиском от lanz,
Примерная (тестовая) конфигурация в архиве. ехе-шник тоже там, если у Вас он запустится.
Собрано на либе 4.5.3 2008-й студией. Сейчас он выглядит ес-сно иначе, как на картинке
которую я давал выше, но для понимания задаваемого вопроса достачен IMHO, но если надо ...
Вопрос в следующем, - как можно избавиться в view-e от узла "xml" выше рута, и по возможности
узлов "#text" ? С минимальными переделками, ес-сно !
С поиском это конечно-же почти не связано, это нужно для правильной инициализации указателя
"DomItem *rootItem" в view-e для последующего поиска узлов DomItem * уже в модуле исполнителя.
Вот конструктор модели в реальном проекте ...
DomModel::DomModel(QDomDocument document, QObject *parent)
: QAbstractItemModel(parent), xmlDocument(document)
{
view = (MdiChild *) parent;
setObjectName( "metadata" ); // for qsa ?
setCompressed( false );
setModified( false );
prjType = false; // Anannas Config for init
rootnode = xmlDocument.documentElement();
nextIdd = nextID();
qDebug() << rootnode.nodeName();
rootItem = new DomItem(xmlDocument, 0);
// rootItem = new DomItem(rootnode, 0);
qDebug() << rootItem->node().nodeName() << " --- " << rootItem->Idd;
init();
}
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)