Отключите QAction, если у элемента QTreeView нет дочерних элементов - PullRequest
0 голосов
/ 25 ноября 2018

У меня 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;
    }
}

h.file

QMenu *contextMenu;

Как проверить, не является ли выбранный элемент из QTreeView родительским для какого-либо элемента и есть ли у него родительский элемент.

Стоит ли включать сюда код QTreeView и QStandardItem, чтобы увидеть, или это не имеет значения?

1 Ответ

0 голосов
/ 25 ноября 2018

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

Я не совсем уверен, соответствует ли это точно требуемому поведению ОП.Возможно, необходимо исправить это условие, но это не так сложно.

...