简体   繁体   English

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

[英]How to hyperlink to an item in a QAbstractItemModel?

Qt versions used: 4.7.1 and 4.8 使用的Qt版本:4.7.1和4.8

I store hierarchical data as nodes in a model that is derived from QAbstractItemModel. 我将分层数据作为节点存储在从QAbstractItemModel派生的模型中。 I have a QTreeView in my application GUI to display the hierarchical data. 我的应用程序GUI中有一个QTreeView来显示分层数据。 (The data being hierarchical may not be essential for this question; the general problem I have applies to any kind of data in any model and view.) (对于这个问题,分层数据可能不是必需的;我遇到的一般性问题适用于任何模型和视图中的任何类型的数据。)

I have a textbox (a QPlainTextEdit widget, but that is not essential) in my application GUI that displays a hyperlink. 我的应用程序GUI中有一个显示超链接的文本框(一个QPlainTextEdit小部件,但这不是必需的)。 When the user clicks on the hyperlink, I can intercept that and obtain the URL of the hyperlink. 当用户单击超链接时,我可以拦截它并获取超链接的URL。 So far, so good. 到现在为止还挺好。

When I intercept that hyperlink, I am going to make the QTreeView navigate to a particular node, expanding its parents as needed so that the user can see it. 当我拦截该超链接时,我将使QTreeView导航到特定节点,并根据需要扩展其父级,以便用户可以看到它。

The URL of the hyperlink will be in format that lets me know a node is being asked for, and will contain identifying information about that particular node. 超链接的URL的格式将使我知道正在请求一个节点,并且将包含有关该特定节点的标识信息。 For example: 例如:

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

So, the question is: What is the something that can identify that particular node, and that can be encoded as a text string? 因此,问题是:什么可以识别特定的节点,并可以将其编码为文本字符串?

I have been reading about QPersistentModelIndex . 我一直在阅读QPersistentModelIndex It sounds like a reasonable thing to start with. 一开始听起来很合理。 At the time I format the hyperlink, I would definitely know the QModelIndex of the particular node, and can construct a QPersistentModelIndex from it. 在格式化超链接时,我肯定会知道特定节点的QModelIndex ,并可以从中构造QPersistentModelIndex But I am getting lost on how to convert that to a string, and then later convert the string back to a QModelIndex from which I can deduce the particular node. 但是我迷路于如何将其转换为字符串,然后将字符串转换回QModelIndex ,从中我可以推断出特定的节点。

Any suggestions are appreciated. 任何建议表示赞赏。

You could declare a custom data role in your model, and for each of your items set a unique value for this 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
    }
    // (...)
}

Then when performing your search, simply use your model's match function to match your unique string and take the first index from the list. 然后,在执行搜索时,只需使用模型的match函数来匹配您的唯一字符串,并从列表中获取第一个索引。

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

You may need to adjust the flags and the start index depending on how you defined your model. 您可能需要根据定义模型的方式来调整标志和起始索引。

Using QAbstractItemModel::match() to search for items in the data model via a custom data role, as suggested by @Cendolt, is an excellent idea. 正如@Cendolt所建议的那样,使用QAbstractItemModel::match()通过自定义数据角色在数据模型中搜索项目是一个好主意。 I was able to use that idea without having to override match() in my custom data model. 我能够使用该想法,而不必在我的自定义数据模型中覆盖match()

The parameters I provide to QAbstractItemModel::match() are a little different, though. 我提供给QAbstractItemModel::match()的参数有些不同。 In combination with the rest of @Cendolt's example, the following works for my situation. 结合@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 );

Valid start index 有效开始索引

Specifying a starting QModelIndex with zeros for the row and column is essential to make the search proceed at all. 为行和列指定QModelIndex至关重要。 When I used a default constructed QModelIndex , the search never called my model's data() method. 当我使用默认构造的QModelIndex ,搜索从未调用我模型的data()方法。 I believe that is because the default constructed QModelIndex has -1 for the row and column, which makes it an invalid index. 我相信这是因为默认构造的QModelIndex对于行和列具有-1,这使其成为无效索引。 In the code for QAbstractItemModel::match() ({Qt dir}\\src\\corelib\\kernel\\qabstractitemmodel.cpp), notice that it skips calling data() if the index is invalid. QAbstractItemModel::match() ({Qt dir} \\ src \\ corelib \\ kernel \\ qabstractitemmodel.cpp)的代码中,请注意,如果索引无效,它将跳过对data()调用。

Match flags 比赛标志

Specifically for hierarchical data, using the Qt::MatchRecursive flag is essential. 特别是对于分层数据,使用Qt::MatchRecursive标志至关重要。 Otherwise, the search does not crawl into child nodes. 否则,搜索不会爬入子节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM