0

使用的 Qt 版本:4.7.1 和 4.8

我将分层数据存储为从 QAbstractItemModel 派生的模型中的节点。我的应用程序 GUI 中有一个QTreeView用于显示分层数据。(分层数据对于这个问题可能不是必需的;我遇到的一般问题适用于任何模型和视图中的任何类型的数据。)

我的应用程序 GUI 中有一个显示超链接的文本框(一个QPlainTextEdit小部件,但这不是必需的)。当用户点击超链接时,我可以拦截它并获取超链接的 URL。到目前为止,一切都很好。

当我截获该超链接时,我将QTreeView导航到特定节点,根据需要扩展其父节点,以便用户可以看到它。

超链接的 URL 将采用让我知道正在请求节点的格式,并将包含有关该特定节点的识别信息。例如:

<a href="node://something">Click me to see node A</a>

所以,问题是:什么东西可以识别特定节点,并且可以编码为文本字符串?

我一直在阅读关于QPersistentModelIndex. 这听起来像是一个合理的开始。在我格式化超链接的时候,我肯定会知道QModelIndex特定节点的,并且可以从中构造一个QPersistentModelIndex。但是我迷失了如何将其转换为字符串,然后再将字符串转换回一个QModelIndex我可以从中推断出特定节点的字符串。

任何建议表示赞赏。

4

2 回答 2

2

您可以在模型中声明自定义数据角色,并为您的每个项目设置此角色的唯一值。

//MyModel.h
class MyModel : public QAbstractItemModel
{
    enum MyRoles {
         UrlRole = Qt::UserRole
    };
    // (...)
}

//MyModel.cpp
QVariant MyModel::data(const QModelIndex &index, int role) const
{
    if (role == UrlRole)
    {
        return "uniqueUrl"; //Up to you to decide what you return here
    }
    // (...)
}

然后在执行搜索时,只需使用模型的匹配函数来匹配您的唯一字符串并从列表中获取第一个索引。

QModelIndex MyDialog::getIndexForUrl(QString myUrl)
{
    QModelIndex index = QModelIndex();
    QModelIndexList resultList = ui->treeView->model()->match(QModelIndex(),
        MyModel::UrlRole, "uniqueUrl", 1, Qt::MatchFixedString | Qt::MatchCaseSensitive);

    if (!resultList.empty())
    {
        index = resultList.first();
    }
    return index;
}

您可能需要根据您定义模型的方式调整标志和开始索引。

于 2019-04-25T05:24:54.660 回答
1

正如@Cendolt 所建议的那样,使用QAbstractItemModel::match()通过自定义数据角色搜索数据模型中的项目是一个好主意。我能够使用这个想法,而无需match()在我的自定义数据模型中进行覆盖。

不过,我提供的参数QAbstractItemModel::match()有些不同。结合@Cendolt 的其余示例,以下适用于我的情况。

QAbstractItemModel * pModel = ...;

// Start searching from the root of the tree.
QModelIndex startIndex = pModel->index( 0, 0 );

QModelIndexList results = p->match(
  startIndex,
  MyModel::UrlRole,
  "uniqueUrl",
  1,
  Qt::MatchRecursive );

有效起始索引

为行和列指定QModelIndex以零开头的值对于使搜索继续进行至关重要。当我使用默认构造QModelIndex时,搜索从未调用我模型的data()方法。我相信这是因为默认构造QModelIndex的行和列具有-1,这使其成为无效索引。在QAbstractItemModel::match()({Qt dir}\src\corelib\kernel\qabstractitemmodel.cpp) 的代码中,请注意data()如果索引无效,它会跳过调用。

匹配标志

特别是对于分层数据,使用Qt::MatchRecursive标志是必不可少的。否则,搜索不会爬入子节点。

于 2019-04-25T15:57:31.870 回答