Reputation: 503
I have QTreeView
populated from database.
I have contextmenu configured as:
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
I have the method to look for a right click to open contextMenu on the item.
void MainWindow::on_treeView_customContextMenuRequested(const QPoint &pos)
{
QModelIndex idx = ui->treeView->indexAt(pos);
if (!idx.isValid())
{return;}
else{
QPoint globalPos = ui->treeView->mapToGlobal(pos);
QAction* selectedItem = contextMenu->exec(globalPos);
if (selectedItem){
qDebug () << selectedItem;
}
}
h.file
QMenu *contextMenu;
How do I check if the selected item from QTreeView
is not a parent of any item & it has a parent.
Should I include QTreeView
and QStandardItem
code here to see or that's irrelevant?
Upvotes: 0
Views: 781
Reputation: 20171
The Qt doc. has a dedicated chapter for this topic:
which I recommend to get an overview.
Concerning the actual question of OP:
How do I check if the selected item from QTreeView is not a parent of any item & it has a parent.
The QTreeView
inherits QAbstractItemView::model()
which provides a pointer to the QAbstractItemModel
which in turn provides the underlying model data for the rendered tree view items.
Any provided QModelIndex
in a view should refer to this model.
The QAbstractItemModel
provides a variety of methods to retrieve data concerning visualization and relations of model items. The QTreeView
uses this but it should be used as well for any added function.
So, selected item is not parent of any item is turned around into "selected item has no children" for which QAbstractItemModel::hasChildren()
is good for:
bool QAbstractItemModel::hasChildren(const QModelIndex &parent = QModelIndex()) const
Returns true if parent has any children; otherwise returns false.
Use rowCount() on the parent to find out the number of children.
Note that it is undefined behavior to report that a particular index hasChildren with this method if the same index has the flag Qt::ItemNeverHasChildren set.
Note: This function can be invoked via the meta-object system and from QML. See Q_INVOKABLE.
See also parent() and index().
and it has a parent can be retrieved using QAbstractItemModel::parent()
:
QModelIndex QAbstractItemModel::parent(const QModelIndex &index) const
Returns the parent of the model item with the given index. If the item has no parent, an invalid QModelIndex is returned.
A common convention used in models that expose tree data structures is that only items in the first column have children. For that case, when reimplementing this function in a subclass the column of the returned QModelIndex would be 0.
When reimplementing this function in a subclass, be careful to avoid calling QModelIndex member functions, such as QModelIndex::parent(), since indexes belonging to your model will simply call your implementation, leading to infinite recursion.
Note: This function can be invoked via the meta-object system and from QML. See Q_INVOKABLE.
See also createIndex().
Putting this together, OPs function should look like this:
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;
}
}
}
I'm not quite sure whether this matches exactly OPs required behavior. It might be necessary to fix the condition but this should be not that hard.
Upvotes: 1