Qt 在 ItemDelegate 之外访问模型数据

2024-04-26

我有一些继承的模型类QAbstractListModel:

VehiclesModel.h:

class VehiclesModel : public QAbstractListModel {
    Q_OBJECT

    public:
        enum Roles {
            ImagePathRole = Qt::UserRole + 1,   // QString
            NameRole                            // QString
        };

        virtual int rowCount(const QModelIndex & parent = QModelIndex()) const override { ... }
        virtual QVariant data(const QModelIndex & index, int role) const override { ... }
        virtual QHash<int, QByteArray> roleNames() const override {
            QHash<int, QByteArray> roles = QAbstractListModel::roleNames();

            roles[ImagePathRole] = "imagePath";
            roles[NameRole] = "name";

            return roles;
        }
};

main.cpp:

#include "VehiclesModel.h"

int main(int argc, char * argv[]) {
    QGuiApplication app(argc, argv);
    VehiclesModel vehiclesModel;
    QQmlApplicationEngine engine;

    engine.rootContext()->setContextProperty("vehiclesModel", &vehiclesModel);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}

And ComboBox显示此模型:main.qml:

ComboBox {
    id: control
    model: vehiclesModel
    delegate: ItemDelegate {
        contentItem: RowLayout {
            Image {
                source: imagePath
            }
            Label {
                text: name
            }
        }
        highlighted: control.highlightedIndex == index
    }
    contentItem: RowLayout {
        Image {
            source: ??imagePath??
        }
        Label {
            text: ??name??
        }
    }
}

我想定制ComboBox显示车辆图像和名称。我可以从以下位置访问模型数据ItemDelegate但如何访问外部的模型数据ItemDelegate?例如我想访问当前索引数据(ImagePathRole and NameRole) 显示车辆图像和名称contentItem.

是否可以在不调用的情况下完成QAbstractListModel直接方法(即index() and data()方法)并制作它们Q_INVOKABLE?


不幸的是,目前还没有以任何合适的内置方式,我发现这是很长一段时间以来所缺乏的,并且我已经考虑在 QML 模型功能中为此实现一些东西,但我还没有时间这样做。

目前,您可以自己做(就像您正在讨论的那样),以类型安全等为代价,或者(我之前通常解决这个问题的方式),您可以创建一个 QObject 子类来表示模型中的单个项目(ItemDataThing 或您选择的任何名称);为其提供源模型和索引、属性,并让它代表模型中数据的单个实例。

就像是:

class ImageDataThing : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString imagePath READ imagePath NOTIFY imagePathChanged)
    Q_PROPERTY(QAbstractItemModel* model READ model WRITE setModel NOTIFY modelChanged)
    Q_PROPERTY(int index READ index WRITE setIndex NOTIFY indexChanged)

public:
    QString imagePath() const;
    QAbstractItemModel *model() const;
    void setModel(const QAbstractItemModel *newModel);
    int index() const;
    void setIndex(int newIndex);
signals:
    void imagePathChanged(const QString &imagePath);
    void modelChanged(QAbstractItemModel *model);
    void indexChanged(int indexChanged);
};

...并且在您的实现中,每当设置模型时,挂钩更改信号(例如 rowsInserted、rowsRemoved...)以更改存储的索引(如果提供)以使其映射到模型中的正确位置。

在模型数据获取器(此处为 imagePath)中,访问模型实例(使用索引)以获取数据并将其返回。

这有一个明显的缺点,那就是有很多样板文件,但另一方面,如果您熟悉模型、类型安全,那么它很容易编写代码,并且可以相当容易地自动生成它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt 在 ItemDelegate 之外访问模型数据 的相关文章

  • 如何在 DataColumn.Expression 中使用 IF/ELSE 或 CASE?

    我有一个包含 1 列的表 状态 我想添加另一列名为 Action 的列 其值如下 如果 Status Yes 则 Action Go 否则 Action Stop 我使用以下代码添加到 操作 列中 但它不起作用 myDataTable Co
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 我如何理解这个 C 类型声明?

    double bar int double double double double 在查看讲座幻灯片时 我发现了留给学生的练习 用简单的英语来说 什么是类型bar在这个 C 声明中 Please帮助我解决这个问题 我什至不知道从哪里开始
  • 何时使用 =default 使析构函数默认?

    尽管对构造函数使用 default 对我来说很清楚 即强制编译器在其他构造函数存在时创建默认构造函数 但我仍然无法理解这两种类型的析构函数之间的区别 那些使用 default 的 那些没有显式定义并由编译器自动生成的 我唯一想到的是 gro
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 信号处理程序有单独的堆栈吗?

    信号处理程序是否有单独的堆栈 就像每个线程都有单独的堆栈一样 这是在 Linux C 环境中 来自 Linux 手册页signal 7 http kernel org doc man pages online pages man7 sign
  • fprintf() 线程安全吗?

    我正在为野人就餐问题的某些变量编写一个 C 解决方案 现在 我创建线程 每个线程都将 FILE 获取到同一个调试文件 在线程内我正在使用 fprintf 进行一些打印 打印的语句不受任何类型的互斥锁等保护 我没有在调试文件中观察到任何交错行
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • 从 WebBrowser 控件 C# 获取滚动值

    我试图在 WebBrowser 控件中获取网页的 Y 滚动索引 但无法访问内置滚动条的值 有任何想法吗 对于标准模式下的 IE 使用文档类型 正如你所说 scrollTop是的财产元素 而不是 HtmlDocument htmlDoc th
  • 为什么 set_symmetry_difference 无法与比较器一起使用?

    Example program include
  • Visual Studio Code:如何配置 includePath 以获得更好的 IntelliSense 结果

    我是使用 Visual Studio Code 的完全初学者 我不知道我在做什么 我已经四处搜索 也许还不够 但我找不到像我这样的人如何配置的简单解释c cpp properties json每当我单击带有绿色波浪线下划线的行旁边的黄色灯泡
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • 跨多个域的 ASP.NET 会话

    是否有合适的 NET 解决方案来在多个域上提供持久服务器会话 即 如果该网站的用户在 www site1 com 下登录 他们也将在 www site2 com 下登录 安全是我们正在开发的程序的一个问题 Thanks 它是否需要在会话中
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐