南海区住房和城乡建设部网站,wordpress手机类主题,软件开发一般要多少钱,长春电商网站建设公司电话https://www.cnblogs.com/jzcn/p/17774676.html
一、属性绑定
这是最简单的方式#xff0c;可以在QML中直接绑定C 对象的属性。通过在C 对象中使用Q_PROPERTY宏定义属性#xff0c;然后在QML中使用绑定语法将属性与QML元素关联起来。
1. person.h
#include QObject可以在QML中直接绑定C 对象的属性。通过在C 对象中使用Q_PROPERTY宏定义属性然后在QML中使用绑定语法将属性与QML元素关联起来。
1. person.h
#include QObjectclass Person : public QObject
{Q_OBJECT/* 使用 Q_PROPERTY 定义交互的属性 */Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)Q_PROPERTY(int age READ getAge WRITE setAge NOTIFY ageChanged)public:explicit Person(QObject *parent nullptr): QObject(parent), m_name(), m_age(0){}/* 为属性提供 getter 和 setter 方法 */QString getName() const { return m_name; }void setName(const QString name) { m_name name; emit nameChanged(); }int getAge() const { return m_age; }void setAge(int age) { m_age age; emit ageChanged(); }signals:/* 信号与属性对应通过信号通知其他对象属性的变化 */void nameChanged();void ageChanged();private:QString m_name;int m_age;
};
2. main.cpp
#include QGuiApplication
#include QQmlApplicationEngine
#include QQmlContext
#include person.hint main(int argc, char *argv[])
{/* 启用Qt应用程序的高DPI缩放功能 */QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);/* 创建一个Qt应用程序的实例 */QGuiApplication app(argc, argv);// 创建Person对象Person person;QQmlApplicationEngine engine;/* 将Person对象作为QML上下文属性 */engine.rootContext()-setContextProperty(person, person);const QUrl url(QStringLiteral(qrc:/main.qml));/* 将 QQmlApplicationEngine 对象的 objectCreated 信号连接到一个 lambda 函数上 *//* lambda 函数用于在 QML 文件中的根对象被创建时进行处理检查对象是否成功创建如果创建失败则退出应用程序 */QObject::connect(engine, QQmlApplicationEngine::objectCreated,app, [url](QObject *obj, const QUrl objUrl) {if (!obj url objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);/* 加载QML文件并显示用户界面 */engine.load(url);return app.exec();
}
3. main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5Window {visible: truewidth: 480height: 800title: qsTr(Hello World)Column {spacing: 10TextField {placeholderText: 请输入姓名text: person.name // 与Person对象的name属性绑定onTextChanged: person.name text // 当文本改变时更新Person对象的name属性}Slider {from: 0to: 100value: person.age // 与Person对象的age属性绑定onValueChanged: person.age value // 当滑块值改变时更新Person对象的age属性}Text {text: 姓名 person.name}Text {text: 年龄 person.age}}}
二、信号与槽
C 对象可以发出信号而QML中的元素可以连接到这些信号上。这样当C 对象的状态发生变化时可以通过信号与槽机制将这些变化传递给QML界面。
1. myobject.h
#include QObject
#include QtDebugclass MyObject : public QObject
{Q_OBJECTpublic:explicit MyObject(QObject *parent nullptr) : QObject(parent) {}signals:void mySignal(QString message);public slots:void mySlot(const QString message) { qDebug() Received message from QML: message; emit mySignal(Hello from C);}
};
2. main.cpp
#include QGuiApplication
#include QQmlApplicationEngine
#include QQmlContext
#include myobject.hint main(int argc, char *argv[])
{/* 启用Qt应用程序的高DPI缩放功能 */QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);/* 创建一个Qt应用程序的实例 */QGuiApplication app(argc, argv);/* 将自定义 C 类型注册到 QML 中的函数, 将自定义 C 类型注册到 QML 中的函数 */qmlRegisterTypeMyObject(com.example, 1, 0, MyObject);QQmlApplicationEngine engine;const QUrl url(QStringLiteral(qrc:/main.qml));/* 将 QQmlApplicationEngine 对象的 objectCreated 信号连接到一个 lambda 函数上 *//* lambda 函数用于在 QML 文件中的根对象被创建时进行处理检查对象是否成功创建如果创建失败则退出应用程序 */QObject::connect(engine, QQmlApplicationEngine::objectCreated,app, [url](QObject *obj, const QUrl objUrl) {if (!obj url objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);/* 加载QML文件并显示用户界面 */engine.load(url);return app.exec();
}
3.main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import com.example 1.0Window {visible: truewidth: 480height: 800title: qsTr(Hello World)/* 定义 sendToCpp 信号 */signal sendToCpp(string message)/* Connections 组件用于连接 myObject 的 onMySignal 信号 */Connections {target: myObjectonMySignal: console.log(Received message from C:, message)}MyObject {id: myObject/* 将 onMySignal 信号传递到 sendToCpp信号上便于 QML 处理 */onMySignal: sendToCpp(message)}Button {text: Send message to Canchors.centerIn: parent/* 单击按钮时会将信号传递到 C 的 mySlot 槽上 */onClicked: myObject.mySlot(Hello from QML)}
}
三、模型视图
模型视图Model-View可以使用C 中的数据模型QStandardItemModel来提供数据给QML界面。QML中的视图元素如ListView或GridView可以使用这些模型来显示数据。 1. mymodel.h
#ifndef MYMODEL_H
#define MYMODEL_H#include QAbstractListModel
#include QListclass MyModel : public QAbstractListModel
{Q_OBJECTpublic:explicit MyModel(QObject *parent nullptr);enum {NameRole Qt::UserRole 1,AgeRole,EmailRole};// 重写以下几个虚函数int rowCount(const QModelIndex parent QModelIndex()) const override;QVariant data(const QModelIndex index, int role Qt::DisplayRole) const override;QHashint, QByteArray roleNames() const override;private:struct Person {QString name;int age;QString email;};QListPerson m_persons;
};#endif // MYMODEL_H
2. mymodel.cpp
#include mymodel.hMyModel::MyModel(QObject *parent): QAbstractListModel(parent)
{// 初始化一些数据m_persons.append({Alice, 25, aliceexample.com});m_persons.append({Bob, 30, bobexample.com});m_persons.append({Charlie, 35, charlieexample.com});
}int MyModel::rowCount(const QModelIndex parent) const
{Q_UNUSED(parent);return m_persons.count();
}QVariant MyModel::data(const QModelIndex index, int role) const
{if (!index.isValid())return QVariant();if (index.row() m_persons.count() || index.row() 0)return QVariant();const Person person m_persons[index.row()];if (role NameRole)return person.name;else if (role AgeRole)return person.age;else if (role EmailRole)return person.email;return QVariant();
}QHashint, QByteArray MyModel::roleNames() const
{QHashint, QByteArray roles;roles[NameRole] name;roles[AgeRole] age;roles[EmailRole] email;return roles;
}
3. main.cpp
#include QGuiApplication
#include QQmlApplicationEngine
#include QQmlContext
#include mymodel.hint main(int argc, char *argv[])
{/* 启用Qt应用程序的高DPI缩放功能 */QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);/* 创建一个Qt应用程序的实例 */QGuiApplication app(argc, argv);QQmlApplicationEngine engine;MyModel myModel;engine.rootContext()-setContextProperty(myModel, myModel);const QUrl url(QStringLiteral(qrc:/main.qml));/* 将 QQmlApplicationEngine 对象的 objectCreated 信号连接到一个 lambda 函数上 *//* lambda 函数用于在 QML 文件中的根对象被创建时进行处理检查对象是否成功创建如果创建失败则退出应用程序 */QObject::connect(engine, QQmlApplicationEngine::objectCreated,app, [url](QObject *obj, const QUrl objUrl) {if (!obj url objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);/* 加载QML文件并显示用户界面 */engine.load(url);return app.exec();
}
4.main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5Window {visible: truewidth: 480height: 800title: qsTr(Hello World)ListView {anchors.fill: parentmodel: myModeldelegate: Item {width: parent.widthheight: 60Column {Text { text: name }Text { text: age }Text { text: email }}}}
}
5.运行效果 四、QML类型注册
QML类型注册QML Type Registration可以将C 对象注册为自定义的QML类型使得QML可以直接创建和使用这些对象。通过在C 中使用 Q_PROPERTY 宏和 Q_INVOKABLE 函数可以将C 类注册为QML类型。我需要这样一个案例 myobject.h
#include QQmlEngine
#include QDebugclass MyObject : public QObject
{Q_OBJECTQ_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:explicit MyObject(QObject *parent nullptr) : QObject(parent) {}QString name() const { return m_name; }void setName(const QString name) { m_name name; emit nameChanged(); }Q_INVOKABLE void printName() { qDebug() Name: m_name; }static void registerQmlType(){qmlRegisterTypeMyObject(com.example, 1, 0, MyObject);}signals:void nameChanged();
private:QString m_name;
};
2. main.cpp
#include QGuiApplication
#include QQmlApplicationEngine
#include QQmlContext
#include myobject.hint main(int argc, char *argv[])
{/* 启用Qt应用程序的高DPI缩放功能 */QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);/* 创建一个Qt应用程序的实例 */QGuiApplication app(argc, argv);QQmlApplicationEngine engine;MyObject::registerQmlType();const QUrl url(QStringLiteral(qrc:/main.qml));/* 将 QQmlApplicationEngine 对象的 objectCreated 信号连接到一个 lambda 函数上 *//* lambda 函数用于在 QML 文件中的根对象被创建时进行处理检查对象是否成功创建如果创建失败则退出应用程序 */QObject::connect(engine, QQmlApplicationEngine::objectCreated,app, [url](QObject *obj, const QUrl objUrl) {if (!obj url objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);/* 加载QML文件并显示用户界面 */engine.load(url);return app.exec();
}
3. main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import com.example 1.0Window {visible: truewidth: 480height: 800title: qsTr(Hello World)MyObject {id: myObjectname: John}/* 垂直布置组件 */Column {anchors.fill: parent // 大小为父组件的大小anchors.margins: 40 // 与父组件四周的间隔spacing: 10 // 子组件之间的间隔Text {text: myObject.name}Button {text: Print NameonClicked: myObject.printName()}}
}