Qt док.есть специальная глава для этой темы:
, которую я рекомендую получить для обзора.
По актуальному вопросу OP:
Как проверить, не является ли выбранный элемент из QTreeView родительским элементом какого-либо элемента и имеет ли он родительский элемент.
QTreeView
наследует QAbstractItemView::model()
, который предоставляет указатель на QAbstractItemModel
, который, в свою очередь, предоставляет базовые данные модели для визуализированных элементов представления дерева.
Любые предоставленные QModelIndex
в представленииследует ссылаться на эту модель.
QAbstractItemModel
предоставляет множество методов для получения данных, касающихся визуализации и отношений элементов модели.QTreeView
использует это, но также должно использоваться для любой добавленной функции.
Таким образом, выбранный элемент не является родительским для любого элемента превращается в "выбранный элемент не имеет дочерних элементов"для которого QAbstractItemModel::hasChildren()
подходит для:
bool QAbstractItemModel :: hasChildren (const QModelIndex & parent = QModelIndex ()) const
Возвращает true, если родительскийесть дети;в противном случае возвращает false.
Используйте rowCount () для родителя, чтобы узнать количество дочерних элементов.
Обратите внимание, что сообщать о том, что конкретный индекс hasChildren с помощью этого метода является неопределенным, если тот же самыйУ индекса установлен флаг Qt :: ItemNeverHasChildren.
Примечание: Эта функция может быть вызвана через систему мета-объектов и из QML.См. Q_INVOKABLE.
См. Также parent () и index ().
и у него есть родительский элемент можно получить с помощью QAbstractItemModel::parent()
:
QModelIndex QAbstractItemModel :: parent (const QModelIndex & index) const
Возвращает родительский элемент элемента модели с указанным индексом.Если у элемента нет родителя, возвращается недопустимый QModelIndex.
Обычное соглашение, используемое в моделях, которые предоставляют древовидные структуры данных, состоит в том, что только элементы в первом столбце имеют дочерние элементы.В этом случае при переопределении этой функции в подклассе столбец возвращаемого QModelIndex будет равен 0.
При переопределении этой функции в подклассе следует избегать вызова функций-членов QModelIndex, таких как QModelIndex :: parent.(), поскольку индексы, принадлежащие вашей модели, будут просто вызывать вашу реализацию, что приведет к бесконечной рекурсии.
Примечание: Эта функция может вызываться через систему мета-объектов и из QML.См. Q_INVOKABLE.
См. Также createIndex ().
Собрав все это вместе, функция OP должна выглядеть следующим образом:
void MainWindow::on_treeView_customContextMenuRequested(const QPoint &pos)
{
QModelIndex idx = ui->treeView->indexAt(pos);
if (!idx.isValid()
|| !ui->treeView->model()->hasChildren(idx)
&& !ui->treeView->model()->parent(idx).isValid()) {
return;
// bail out -> no context menu for leaf nodes or toplevel nodes
} else {
QPoint globalPos = ui->treeView->mapToGlobal(pos);
QAction* selectedItem = contextMenu->exec(globalPos);
if (selectedItem) {
qDebug () << selectedItem;
}
}
}
Я не совсем уверен, соответствует ли это точно требуемому поведению ОП.Возможно, необходимо исправить это условие, но это не так сложно.