C++ 与 QML交互
  JCsIkAITQy58 2023年11月02日 42 0

前言

在 QT 中 既然 qml处理前端,C++处理后端,那么 C++ 和 QML 是如何进行交互?

将对象暴露给 qml

void QQmlContext::setContextProperty(const QString &name, QObject *value)
Set the value of the name property on this context.
QQmlContext does not take ownership of value.

这样在 qml 中可以通过 name对象直接使用对象的属性或者方法。

  1. 对象的方法 要求必须是 公共的槽函数,或者是被 Q_INVOKABLE 修饰的普通公有函数。代码如下
//MyClass.cpp
#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = nullptr);
    Q_INVOKABLE int sum(int a, int b);

signals:

public slots:
    void print();
};

#endif // MYCLASS_H
//main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "MyClass.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    MyClass *myClass = new MyClass;

    QQmlApplicationEngine engine;
    QQmlContext *context = engine.rootContext();
    context->setContextProperty("myClass", myClass);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Component.onCompleted: {
        myClass.print();
        console.log(myClass.sum(1, 2));
    }
}

将C++中类的属性暴露给qml。使用 Q_PROPERTY(...)进行暴露

  class Message : public QObject
  {
      Q_OBJECT
      Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
  public:
      void setAuthor(const QString &a) {
          if (a != m_author) {
              m_author = a;
              emit authorChanged();
          }
      }
      QString author() const {
          return m_author;
      }
  signals:
      void authorChanged();
  private:
      QString m_author;
  };
  int main(int argc, char *argv[]) {
      QGuiApplication app(argc, argv);

      QQuickView view;
      Message msg;
      view.engine()->rootContext()->setContextProperty("msg", &msg);
      view.setSource(QUrl::fromLocalFile("MyItem.qml"));
      view.show();

      return app.exec();
  }
  // MyItem.qml
  import QtQuick 2.0

  Text {
      width: 100; height: 100
      text: msg.author    // invokes Message::author() to get this value

      Component.onCompleted: {
          msg.author = "Jonah"  // invokes Message::setAuthor()
      }
  }

注意 这句话 QQmlContext does not take ownership of value. 也就是说 在使用 setContextProperty 应该注意暴露对象的生命周期。

在QML中注册C++对象

qmlRegisterType<Person>("LiBai.Person", 1, 0, "Person");
//person.cpp
#include "Person.h"
#include <QDebug>

Person::Person(QObject *parent) : QObject(parent), m_name(QStringLiteral("小明")), m_age(18)
{

}

void Person::print()
{
    qDebug() << "name : " << m_name << " age : " << m_age;
}

//Person.h
#ifndef PERSON_H
#define PERSON_H

#include <QObject>
#include <QString>

class Person : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(int age READ age WRITE setAge NOTIFY ageChaged)
public:
    explicit Person(QObject *parent = nullptr);
    Q_INVOKABLE void print();

    QString name() const
    {
        return m_name;
    }

    int age() const
    {
        return m_age;
    }

signals:

    void nameChanged(QString name);

    void ageChaged(int age);

public slots:
void setName(QString name)
{
    if (m_name == name)
        return;

    m_name = name;
    emit nameChanged(m_name);
}

void setAge(int age)
{
    if (m_age == age)
        return;

    m_age = age;
    emit ageChaged(m_age);
}

private:
    QString m_name;
    int m_age;
};

#endif // PERSON_H
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
import LiBai.Person 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    Item{
        id: rootItem
        anchors.fill: parent
        ColumnLayout{
            id: columnLayout
            anchors.fill: parent
            Rectangle{
                id: rect
                Layout.preferredHeight: 240
                Layout.preferredWidth: columnLayout.width
                Layout.fillHeight: true
                color: "blue"
                Text{
                    anchors.centerIn: parent
                    color: "white"
                    text: person.name + " " + person.age
                }
                Person{
                    id: person
                    name: "老王"
                    age: 23
                }
            }
            Rectangle{
                id: rect_1
                Layout.preferredHeight: 240
                Layout.preferredWidth: columnLayout.width
                Layout.fillHeight: true
                color: "red"
                Text{
                    anchors.centerIn: parent
                    color: "white"
                    text: person_1.name + " " + person_1.age
                }
                Person{
                    id: person_1
                }
            }
        }
    }
}

注意: 在写完 如下代码后 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) 可以将鼠标光标放在 Q_PROPERTY上,然后 组合键alt + enterQtCreator就可以自动生成代码。在QML中注册C++类型适合于要重复使用的情况

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  lA9hNJ8xYnRP   2023年12月12日   30   0   0 Qt
  lA9hNJ8xYnRP   2023年12月06日   31   0   0 Qt
  gBkHYLY8jvYd   2023年12月06日   50   0   0 #includecii++
  lA9hNJ8xYnRP   2023年12月06日   34   0   0 构造函数Qt
  lA9hNJ8xYnRP   2023年12月07日   30   0   0 Qt
  lA9hNJ8xYnRP   2023年12月11日   27   0   0 Qt
  gBkHYLY8jvYd   2023年12月10日   18   0   0 #include邻域灰度图像
  gBkHYLY8jvYd   2023年12月10日   22   0   0 #include数组i++
  gBkHYLY8jvYd   2023年12月06日   19   0   0 #includeios数据
  gBkHYLY8jvYd   2023年12月08日   20   0   0 #includecii++
  lA9hNJ8xYnRP   2023年11月25日   38   0   0 Qt数据
  lA9hNJ8xYnRP   2023年11月30日   30   0   0 Qt表视图
  gBkHYLY8jvYd   2023年11月22日   23   0   0 #include十进制高精度
JCsIkAITQy58