经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
利用上下文属性将 C++ 对象嵌入 QML 里
来源:jb51  时间:2021/12/15 8:46:13  对本文有异议

QQmlContext 类使将 C++ 数据注入 QML 对象的能力成为可能。此类向 QML 对象的上下文公开数据,以便可以直接从 QML 代码范围内引用数据。

一、设置简单的上下文属性

例如,这里有一个 QML 项,它引用了当前作用域中不存在的 currentDateTime 值:

  1. // MyItem.qml
  2. import QtQuick 2.0
  3. Text
  4. {
  5. text: currentDateTime
  6. }
  7.  
  8.  

这个值可以由加载 QML 组件的 C++ 应用程序使用 QQmlContext::setContextProperty() 直接设置:

  1. QQuickView view;
  2. view.rootContext()->setContextProperty("currentDateTime",QDateTime::currentDateTime());
  3. view.setSource(QUrl::fromLocalFile("MyItem.qml"));
  4. view.show();
  5.  
  6.  

由于在 QML 中计算的所有表达式都是在特定上下文中计算的,如果修改了上下文,则将重新计算该上下文中的所有绑定。因此,应在应用程序初始化之外谨慎使用上下文属性,因为这可能会导致应用程序性能下降。

二、将对象设置为上下文属性

上下文属性可以包含 QVariant QObject* 值。 这意味着也可以使用这种方法注入自定义 C++ 对象,并且可以直接在 QML 中修改和读取这些对象。修改上面的例子,嵌入一个 QObject 实例而不是一个 QDateTime 值,QML 代码在对象实例上调用一个方法:

  1. class ApplicationData : public QObject
  2. {
  3. Q_OBJECT
  4. public:
  5. Q_INVOKABLE QDateTime getCurrentDateTime() const
  6. {
  7. return QDateTime::currentDateTime();
  8. }
  9. };
  10. int main(int argc, char *argv[])
  11. {
  12. QGuiApplication app(argc, argv);
  13. ApplicationData data;
  14. QQuickView view;
  15. view.rootContext()->setContextProperty("applicationData", &data);
  16. view.setSource(QUrl::fromLocalFile("MyItem.qml"));
  17. view.show();
  18. return app.exec();
  19. }
  20. // MyItem.qml
  21. import QtQuick 2.0
  22. Text
  23. {
  24. text: applicationData.getCurrentDateTime()
  25. }
  26.  
  27.  

请注意:从 C++ 返回到 QML 的日期/时间值可以通过 Qt.formatDateTime() 和相关函数进行格式化。

如果 QML 项需要从上下文属性接收信号,它可以使用 Connections 类型连接到它们。 例如,如果 ApplicationData 有一个名为 dataChanged() 的信号,则可以使用 Connections 对象中的 onDataChanged 处理程序连接到该信号:

  1. Text
  2. {
  3. text: applicationData.getCurrentDateTime()
  4. Connections
  5. {
  6. target: applicationData
  7. onDataChanged: console.log("The application data changed!")
  8. }
  9. }
  10.  

三、上下文属性与C++ 的数据模型示例

3.1、字符串列表模型

  1. int main(int argc, char ** argv)
  2. {
  3. QGuiApplication app(argc, argv);
  4. QStringList dataList;
  5. dataList.append("Item 1");
  6. dataList.append("Item 2");
  7. dataList.append("Item 3");
  8. dataList.append("Item 4");
  9. QQuickView view;
  10. QQmlContext *ctxt = view.rootContext();
  11. ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
  12. view.setSource(QUrl("qrc:view.qml"));
  13. view.show();
  14. return app.exec();
  15. }
  16.  
  17.  
  1. import QtQuick 2.0
  2. ListView
  3. {
  4. width: 100; height: 100
  5. model: myModel
  6. delegate: Rectangle
  7. {
  8. height: 25
  9. width: 100
  10. Text { text: modelData }
  11. }
  12. }
  13.  

3.2、对象列表模型

  1. #ifndef DATAOBJECT_H
  2. #define DATAOBJECT_H
  3. #include <QObject>
  4. class DataObject : public QObject
  5. {
  6. Q_OBJECT
  7. Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
  8. Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
  9. public:
  10. DataObject(QObject *parent=nullptr);
  11. DataObject(const QString &name, const QString &color, QObject *parent=nullptr);
  12. QString name() const;
  13. void setName(const QString &name);
  14. QString color() const;
  15. void setColor(const QString &color);
  16. signals:
  17. void nameChanged();
  18. void colorChanged();
  19. private:
  20. QString m_name;
  21. QString m_color;
  22. };
  23. #endif // DATAOBJECT_H
  24.  
  25.  
  1. #include <QDebug>
  2. #include "dataobject.h"
  3. DataObject::DataObject(QObject *parent)
  4. : QObject(parent)
  5. {
  6. }
  7. DataObject::DataObject(const QString &name, const QString &color, QObject *parent)
  8. : QObject(parent), m_name(name), m_color(color)
  9. {
  10. }
  11. QString DataObject::name() const
  12. {
  13. return m_name;
  14. }
  15. void DataObject::setName(const QString &name)
  16. {
  17. if (name != m_name)
  18. {
  19. m_name = name;
  20. emit nameChanged();
  21. }
  22. }
  23. QString DataObject::color() const
  24. {
  25. return m_color;
  26. }
  27. void DataObject::setColor(const QString &color)
  28. {
  29. if (color != m_color)
  30. {
  31. m_color = color;
  32. emit colorChanged();
  33. }
  34. }
  35. #include "dataobject.h"
  36. int main(int argc, char ** argv)
  37. {
  38. QGuiApplication app(argc, argv);
  39. QList<QObject*> dataList;
  40. dataList.append(new DataObject("Item 1", "red"));
  41. dataList.append(new DataObject("Item 2", "green"));
  42. dataList.append(new DataObject("Item 3", "blue"));
  43. dataList.append(new DataObject("Item 4", "yellow"));
  44. QQuickView view;
  45. view.setResizeMode(QQuickView::SizeRootObjectToView);
  46. QQmlContext *ctxt = view.rootContext();
  47. ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
  48. view.setSource(QUrl("qrc:view.qml"));
  49. view.show();
  50. return app.exec();
  51. }
  52. import QtQuick 2.0
  53. ListView
  54. {
  55. width: 100; height: 100
  56. model: myModel
  57. delegate: Rectangle
  58. {
  59. height: 25
  60. width: 100
  61. color: model.modelData.color
  62. Text { text: name }
  63. }
  64. }
  65.  

3.3、QAbstractItemModel

  1. #include <QAbstractListModel>
  2. #include <QStringList>
  3. class Animal
  4. {
  5. public:
  6. Animal(const QString &type, const QString &size);
  7. QString type() const;
  8. QString size() const;
  9. private:
  10. QString m_type;
  11. QString m_size;
  12. };
  13. class AnimalModel : public QAbstractListModel
  14. {
  15. Q_OBJECT
  16. public:
  17. enum AnimalRoles
  18. {
  19. TypeRole = Qt::UserRole + 1,
  20. SizeRole
  21. };
  22. AnimalModel(QObject *parent = nullptr);
  23. void addAnimal(const Animal &animal);
  24. int rowCount(const QModelIndex & parent = QModelIndex()) const;
  25. QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
  26. protected:
  27. QHash<int, QByteArray> roleNames() const;
  28. private:
  29. QList<Animal> m_animals;
  30. };
  31.  
  32.  
  1. #include "model.h"
  2. Animal::Animal(const QString &type, const QString &size)
  3. : m_type(type), m_size(size)
  4. {
  5. }
  6. QString Animal::type() const
  7. {
  8. return m_type;
  9. }
  10. QString Animal::size() const
  11. {
  12. return m_size;
  13. }
  14. AnimalModel::AnimalModel(QObject *parent)
  15. : QAbstractListModel(parent)
  16. {
  17. }
  18. void AnimalModel::addAnimal(const Animal &animal)
  19. {
  20. beginInsertRows(QModelIndex(), rowCount(), rowCount());
  21. m_animals << animal;
  22. endInsertRows();
  23. }
  24. int AnimalModel::rowCount(const QModelIndex & parent) const
  25. {
  26. Q_UNUSED(parent)
  27. return m_animals.count();
  28. }
  29. QVariant AnimalModel::data(const QModelIndex & index, int role) const
  30. {
  31. if (index.row() < 0 || index.row() >= m_animals.count())
  32. return QVariant();
  33. const Animal &animal = m_animals[index.row()];
  34. if (role == TypeRole)
  35. return animal.type();
  36. else if (role == SizeRole)
  37. return animal.size();
  38. return QVariant();
  39. }
  40. QHash<int, QByteArray> AnimalModel::roleNames() const
  41. {
  42. QHash<int, QByteArray> roles;
  43. roles[TypeRole] = "type";
  44. roles[SizeRole] = "size";
  45. return roles;
  46. }
  47. int main(int argc, char ** argv)
  48. {
  49. QGuiApplication app(argc, argv);
  50. AnimalModel model;
  51. model.addAnimal(Animal("Wolf", "Medium"));
  52. model.addAnimal(Animal("Polar bear", "Large"));
  53. model.addAnimal(Animal("Quoll", "Small"));
  54. QQuickView view;
  55. view.setResizeMode(QQuickView::SizeRootObjectToView);
  56. QQmlContext *ctxt = view.rootContext();
  57. ctxt->setContextProperty("myModel", &model);
  58. view.setSource(QUrl("qrc:view.qml"));
  59. view.show();
  60. return app.exec();
  61. }
  62.  
  1. import QtQuick 2.0
  2. ListView
  3. {
  4. width: 200; height: 250
  5. model: myModel
  6. delegate: Text { text: "Animal: " + type + ", " + size }
  7. }

到此这篇关于利用上下文属性将 C++ 对象嵌入 QML 里的文章就介绍到这了,更多相关? C++ 对象嵌入 QML 里内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号