我已经从数据库中填充了QTreeView

我有contextmenu配置为:

ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);


我有寻找右键单击以打开该项目上的contextMenu的方法。

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;
    }
}


文件

QMenu *contextMenu;


如何检查从QTreeView中选择的项目是否不是任何项目的父项,并且是否具有父项。

我应该在此处包含QTreeViewQStandardItem代码以查看还是无关紧要?

最佳答案

Qt文件。有一个专门的章节用于该主题:

Model/View Programming

我建议您对其进行概述。

关于OP的实际问题:


  如何检查从QTreeView中选择的项是否不是任何项的父项,并且它是否具有父项。


QTreeView继承了QAbstractItemView::model(),后者提供了指向QAbstractItemModel的指针,而该指针又为呈现的树视图项提供了基础模型数据。

视图中提供的任何QModelIndex都应引用此模型。

QAbstractItemModel提供了多种方法来检索有关模型项的可视化和关系的数据。 QTreeView使用此功能,但也应将其用于任何附加功能。

因此,所选项目不是父项,任何项都将转为QAbstractItemModel::hasChildren()对以下项有利的“所选项目没有子项”:


  布尔QAbstractItemModel :: hasChildren(const QModelIndex&parent = QModelIndex())const
  
  如果parent有任何孩子,则返回true;否则返回false。
  
  在父级上使用rowCount()来找出子级数。
  
  请注意,如果同一索引设置了标志Qt :: ItemNeverHasChildren,则使用此方法报告特定索引hasChildren是未定义的行为。
  
  注意:可以通过元对象系统和QML调用此函数。请参阅Q_INVOKABLE。
  
  另请参见parent()和index()。


它具有一个父对象,可以使用QAbstractItemModel::parent()进行检索:


  QModelIndex QAbstractItemModel :: parent(const QModelIndex&index)const
  
  返回具有给定索引的模型项的父项。如果该项没有父项,则返回无效的QModelIndex。
  
  在公开树数据结构的模型中使用的常见约定是,只有第一列中的项目才有子级。对于这种情况,当在子类中重新实现此函数时,返回的QModelIndex的列将为0。
  
  在子类中重新实现此函数时,请小心避免调用QModelIndex成员函数,例如QModelIndex :: parent(),因为属于您模型的索引将仅调用您的实现,从而导致无限递归。
  
  注意:可以通过元对象系统和QML调用此函数。请参阅Q_INVOKABLE。
  
  另请参见createIndex()。


综上所述,OPs功能应如下所示:

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;
        }
    }
}


我不太确定这是否与OP所需的行为完全匹配。可能有必要解决此问题,但这并不难。

关于c++ - 如果QTreeView项没有子项,则禁用QAction,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53467239/

10-11 18:17