如何超链接到QAbstractItemModel中的项目?

时间:2019-04-24 22:58:58

标签: c++ qt qabstractitemmodel qabstractitemview

使用的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,由此可以推断出特定的节点。

任何建议都值得赞赏。

2 个答案:

答案 0 :(得分:2)

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

//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
    }
    // (...)
}

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

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

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

答案 1 :(得分: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标志。否则,搜索不会爬入子节点。