说明,主要是对QT的文档内例子进行的一些分别解说,希望更容易的理解 C++导出到QML的过程。 1.导出一个简单的类Person 2.具体导出过程 假设我们要导出一个Person类, A 那么就要考虑如何的一个类他才可以导出呢? 他需要符合一定的条件 1.继承自QObject 2.有默认构造函数 B 如何导出呢? 通过一个函数 int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) int qmlRegisterType() 3.具体的例子 // person.h [cpp] view plaincopyprint? #ifndef PERSON_H #define PERSON_H #include class Person : public QObject { Q_OBJECT public: explicit Person(QObject *parent = 0); }; #endif // PERSON_H // person.cpp #include "person.h" Person::Person(QObject *parent) : QObject(parent) { } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType("People",1,0,"Person"); //qmlRegisterType(); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); return a.exec(); } // UICtest.qml import Qt 4.7 import People 1.0 //如果是qmlRegisterType(); 导出就可以注释这条 Rectangle { width: 640 height: 480 Person{} } 说明:我们通过qmlRegisterType("People",1,0,"Person"); 向QML中导出Person类,这个类在People包中,在QML中需要使用Person类的 话就必须包含People包,通过import People 1.0来包含,之后就可以使用Person 创建对象使用来。 QML与c++交互学习笔记(二) 1.导出Person类中的成员方法 2.具体导出过程 导出的方法有 1.使用Q_INVOKABLE 2.使用 槽机制 3.具体代码 // person.h [cpp] view plaincopyprint? #ifndef PERSON_H #define PERSON_H #include class Person : public QObject { Q_OBJECT public: explicit Person(QObject *parent = 0); Q_INVOKABLE void FirstEcho(void); public slots: void SecondEcho(void); }; #endif // PERSON_H // person.cpp [cpp] view plaincopyprint? #include "person.h" Person::Person(QObject *parent) : QObject(parent) { } void Person::FirstEcho(void) { // 简简单单打印一句话 qDebug("call Person::FirstEcho"); } void Person::SecondEcho(void) { qDebug("call Person::SecondEcho"); } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType("People",1,0,"Person"); //qmlRegisterType(); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); return a.exec(); } // UICtest.qml import Qt 4.7 import People 1.0 //如果是qmlRegisterType(); 导出就可以注释这条 Rectangle { width: 640 height: 480 Person{ id: per;} MouseArea{ anchors.fill: parent; onClicked:{ per.FirstEcho(); per.SecondEcho(); } } } 说明: 这里导出了两个函数分别是FirstEcho 和SecondEcho 两个函数,这两个函数本别是使用 FirstEcho使用使用 Q_INVOKABLE导出,SecondEcho直接使用槽。 调用函数在控制台输出一些信息,这里是在鼠标点击界面后出发的。 QML与c++交互学习笔记(三) 1.导出Person类中的属性 2.具体导出过程 1.导出Person一个颜色属性,一个int属性 注意 1. 当需要实现属性变化其他引用到此属性的属性也跟着变化的情况的话,需要设置属性相应的信号 2. 设置属性的时候,使用的类型必须是已经导出到QML中的类型 3.具体代码 // person.h [cpp] view plaincopyprint? #ifndef PERSON_H #define PERSON_H #include #include class Person : public QObject { Q_OBJECT // 设置设置属性的名字是 bgcolor // 对应读取函数名字 bgColor // 对应写函数名字 setBgColor // 属性发生改变后发送信号 sendBgColorChange Q_PROPERTY(QColor bgcolor READ getBgColor WRITE setBgColor NOTIFY sendBgColorChange) // 设置设置属性的名字是 count // 对应读取函数名字 getCount // 对应写函数名字 setCount // 属性发生改变后发送信号 sendCountChange Q_PROPERTY(int count READ getCount WRITE setCount NOTIFY sendCountChange) public: explicit Person(QObject *parent = 0); QColor getBgColor(void) const; void setBgColor(const QColor& color); int getCount(void); void setCount(int count); signals: void sendBgColorChange(void); void sendCountChange(void); private: QColor m_Color; int m_Count; }; #endif // PERSON_H // person.cpp [cpp] view plaincopyprint? #include "person.h" //--------------------------------- // Person::Person(QObject *parent) : QObject(parent), m_Color("blue"), m_Count(0) { } //--------------------------------- // QColor Person::getBgColor(void) const { return m_Color; } //--------------------------------- // void Person::setBgColor(const QColor& color) { m_Color = color; emit sendBgColorChange(); } //--------------------------------- // int Person::getCount(void) { return m_Count; } //--------------------------------- // void Person::setCount(int count) { m_Count = count; emit sendCountChange(); } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType("People",1,0,"Person"); //qmlRegisterType(); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); return a.exec(); } // UICtest.qml import Qt 4.7 import People 1.0 //如果是qmlRegisterType(); 导出就可以注释这条 Rectangle { width: 640 height: 480 color: per.bgcolor; Person{ id: per;} Text { id: textlabel; text: "text " + per.count; } MouseArea{ anchors.fill: parent; onClicked:{ // 当鼠标按下后,由于属性上有信号,当属性发生改变后, // 所有引用此属性的值的都相应的发生改变 per.bgcolor = "red"; per.count = 20; } } } 说明: 在person类中,设置了两个属性bgcolor, count ,他们分别在发送改变后调用自己对应的信号 具体看源代码,这里是设置来矩形框的颜色,文本框中文本。 QML与c++交互学习笔记(四) 1.导出Person类,并且一个Job类,Job类包含一个Person的指针 2.具体导出过程 1.通过属性来实现,具体的请看代码 3.具体代码 // person.h [cpp] view plaincopyprint? #ifndef PERSON_H #define PERSON_H #include #include class Person : public QObject { Q_OBJECT // 设置设置属性的名字是 name // 对应读取函数名字 getName // 对应写函数名字 setName // 属性发生改变后发送信号 sendNameChange Q_PROPERTY(QString name READ getName WRITE setName NOTIFY sendNameChange) // 设置设置属性的名字是 age // 对应读取函数名字 getAge // 对应写函数名字 setAge // 属性发生改变后发送信号 sendAgeChange Q_PROPERTY(int age READ getAge WRITE setAge NOTIFY sendAgeChange) public: explicit Person(QObject *parent = 0); QString getName(void) const; void setName(const QString& name); int getAge(void); void setAge(int age); signals: void sendNameChange(void); void sendAgeChange(void); private: QString m_Name; int m_Age; }; /* 设想一份工作给予一个人 */ class Job : public QObject { Q_OBJECT Q_PROPERTY(Person *per READ getPerson WRITE setPerson NOTIFY sendPersonChange) Q_PROPERTY(QString jn READ getJobName WRITE setJobName NOTIFY sendJobNameChange) public: explicit Job(QObject *parent = 0); ~Job(); void setPerson(Person *per); Person *getPerson(void) const; void setJobName(const QString & jobname); QString getJobName(void) const; signals: void sendPersonChange(); void sendJobNameChange(); private: Person *m_Person; QString m_JobName; }; #endif // PERSON_H // person.cpp [cpp] view plaincopyprint? #include "person.h" //--------------------------------- // Person::Person(QObject *parent) : QObject(parent), m_Name("unknow"), m_Age(0) { } //--------------------------------- // QString Person::getName(void) const { return m_Name; } //--------------------------------- // void Person::setName(const QString& name) { m_Name = name; emit sendNameChange(); } //--------------------------------- // int Person::getAge(void) { return m_Age; } //--------------------------------- // void Person::setAge(int age) { m_Age = age; emit sendAgeChange(); } //--------------------------------- // Job::Job(QObject *parent) :QObject(parent), m_Person(0), m_JobName("unknown") { } //--------------------------------- // Job::~Job() { } //--------------------------------- // void Job::setPerson(Person *per) { m_Person = per; emit sendPersonChange(); } //--------------------------------- // Person *Job::getPerson(void) const { return m_Person; } //--------------------------------- // void Job::setJobName(const QString & jobname) { m_JobName = jobname; emit sendJobNameChange(); } //--------------------------------- // QString Job::getJobName(void) const { return m_JobName; } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType("People",1,0,"Person"); //qmlRegisterType(); qmlRegisterType("People",1,0,"Job"); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); return a.exec(); } // UICtest.qml import Qt 4.7 import People 1.0 //如果是qmlRegisterType(); 导出就可以注释这条 Rectangle { width: 640 height: 480 Job { id: jobA; jn: "Learn"; per: Person { id: ps; name: "Luly"; age: 25; } } // 显示这份工作的一些信息 Rectangle{ x: 100; y: 100; width: 100; height: 100; Text { text: "Job name:" + jobA.jn; } Text { y: 20; text: "Person name:" + ps.name; } Text { y: 40; text: "Person age:" + ps.age; } } MouseArea{ anchors.fill: parent; onClicked:{ // 我要改变工作的名字 工作人的信息 jobA.jn = "Clean House"; ps.name = "Tom"; ps.age = 30; } } } 说明: 主要是导出了两个类Person和Job, Job 包含一个Person的指针,这样后,可以看到 在QML中,我们需要给予Job对象一个Person来尽心赋值。 QML与c++交互学习笔记(五) 1.导出Person类,并且一个PersonGroup类,PersonGroup类是Person的一个组 2.具体导出过程 1.通过属性来实现,具体的请看代码 3.具体代码 // person.h [cpp] view plaincopyprint? #ifndef PERSON_H #define PERSON_H #include #include #include class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ getName WRITE setName NOTIFY sendNameChange) Q_PROPERTY(int age READ getAge WRITE setAge NOTIFY sendAgeChange) public: explicit Person(QObject *parent = 0); QString getName(void) const; void setName(const QString& name); int getAge(void); void setAge(int age); signals: void sendNameChange(void); void sendAgeChange(void); private: QString m_Name; int m_Age; }; class PersonGroup : public QObject { Q_OBJECT Q_PROPERTY(QDeclarativeListPropertymembers READ members) public: explicit PersonGroup(QObject *parent = 0); QDeclarativeListPropertymembers(void); Q_INVOKABLE int membersCount(void) const; Q_INVOKABLE Person *member(int index) const; private: QListm_MemberList; }; #endif // PERSON_H // person.cpp [cpp] view plaincopyprint? #include "person.h" //--------------------------------- // Person::Person(QObject *parent) : QObject(parent), m_Name("unknow"), m_Age(0) { } //--------------------------------- // QString Person::getName(void) const { return m_Name; } //--------------------------------- // void Person::setName(const QString& name) { m_Name = name; emit sendNameChange(); } //--------------------------------- // int Person::getAge(void) { return m_Age; } //--------------------------------- // void Person::setAge(int age) { m_Age = age; emit sendAgeChange(); } //--------------------------------- // PersonGroup::PersonGroup(QObject *parent) :QObject(parent) { } //--------------------------------- // QDeclarativeListPropertyPersonGroup::members(void) { return QDeclarativeListProperty(this, m_MemberList); } //--------------------------------- // int PersonGroup::membersCount() const { return m_MemberList.size(); } //--------------------------------- // Person *PersonGroup::member(int index) const { return m_MemberList.at(index); } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType("People",1,0,"Person"); //qmlRegisterType(); qmlRegisterType("People",1,0,"PersonGroup"); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); return a.exec(); } // UICtest.qml import Qt 4.7 import People 1.0 //如果是qmlRegisterType(); 导出就可以注释这条 Rectangle { width: 640 height: 480 property int pgcurIndex: 0; PersonGroup{ id: group; members: [ Person { name: "A"; age: 20}, Person { name: "B"; age: 21}, Person { name: "C"; age: 22}, Person { name: "D"; age: 23}, Person { name: "E"; age: 24} ] } // 显示这份工作的一些信息 Rectangle{ x: 100; y: 100; width: 100; height: 100; Text { id: text1; text: ""} Text { id: text2; y: 20; text: ""} Text { id: text3; y: 40; text: ""} } MouseArea{ anchors.fill: parent; onClicked:{ //if (pgcurIndex < group.membersCount() - 1){ // 这里两种方法都可以 if (pgcurIndex < group.members.length - 1){ pgcurIndex++; }else{ pgcurIndex = 0; } // 显示信息 text1.text = "PersonGroup index: " + pgcurIndex; var person = group.member(pgcurIndex); text2.text = "Person name: " + person.name; text3.text = "Person age: " + person.age; } } } 说明: 这里导出了两个类Person, PersonGroup, PersonGroup保存来一个Person的组, 我们通过导出的函数来调用类面的成员,获取成员的信息. QML与c++交互学习笔记(六) 关于qt c++中创建对象,QML获取此对象数据问题 1.假设 1.在c++中创建一个Person的对象, 2.在QML中获取并显示数据 3.在c++中改变数据后,显示的数据能进行相应的改变 也就是说我们实际是在c++中new一个对象出来,而把这个对象的数据在QML里面进行显示 2.具体代码 // person.h [cpp] view plaincopyprint? #ifndef PERSON_H #define PERSON_H #include #include #include #include class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ getName WRITE setName NOTIFY sendNameChange) Q_PROPERTY(int age READ getAge WRITE setAge NOTIFY sendAgeChange) public: explicit Person(QObject *parent = 0); QString getName(void) const; void setName(const QString& name); int getAge(void); void setAge(int age); // 一个简单的函数, 获取蓝色 Q_INVOKABLE QColor getColor(void) const; Q_INVOKABLE void changeNameAndAge(void); signals: void sendNameChange(void); void sendAgeChange(void); private: QString m_Name; int m_Age; }; #endif // PERSON_H // person.cpp [cpp] view plaincopyprint? #include "person.h" //--------------------------------- // Person::Person(QObject *parent) : QObject(parent), m_Name("unknow"), m_Age(0) { } //--------------------------------- // QString Person::getName(void) const { return m_Name; } //--------------------------------- // void Person::setName(const QString& name) { m_Name = name; emit sendNameChange(); } //--------------------------------- // int Person::getAge(void) { return m_Age; } //--------------------------------- // void Person::setAge(int age) { m_Age = age; emit sendAgeChange(); } //--------------------------------- // QColor Person::getColor(void) const { return QColor(Qt::blue); } //--------------------------------- // void Person::changeNameAndAge(void) { setName("Luly"); setAge(31); } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Person tmpPerson; tmpPerson.setName("Tom"); tmpPerson.setAge(25); QDeclarativeView qmlView; qmlView.rootContext()->setContextProperty("ps",&tmpPerson); qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); return a.exec(); } // UICtest.qml import Qt 4.7 Rectangle { width: 640 height: 480 Text { text: "Person name:" + ps.name; } Text { y: 20; text: "Person age:" + ps.age; } Rectangle{ x: 20; y: 40; width: 20; height: 20; color: ps.getColor();} MouseArea{ anchors.fill: parent; // 当鼠标按下后改变名字和年龄 onClicked: { ps.changeNameAndAge(); } } } 说明: 我们在c++中创建来一个对象,并且在把这个对象导出给QML调用用,我们设置来属性,QML中可以直接使用属性来进行赋值. QML与c++交互学习笔记(七) 1.假设这样一种情况 我这里由一个Wideget 继承自QWidget上面添加来一个QLabel, 一个QPushButton 我如何把这个Wideget放到QML中使用,那么我当QPushButton 按下后我怎么在QML中进行处理呢? 我这里指出一种方法 让Wideget 继承QGraphicsProxyWidget,对Wideget进行导出,在QML中创建 此对象,在他导出的信中进行处理,具体代码。 还有就是这个网址上说明来很多QML与c++之间通讯的方法,很悲剧的是我的assistant中却没有者部分,不知道版本低还是怎么的。 http://doc.qt./4.7-snapshot/qtbinding.html 2.具体代码 //widget.h [cpp] view plaincopyprint? #ifndef WIDGET_H #define WIDGET_H #include #include #include #include #include class Widget : public QGraphicsProxyWidget { Q_OBJECT public: explicit Widget(QGraphicsItem *parent = 0); ~Widget(); Q_INVOKABLE void changeText(const QString& s); signals: void sendOnButton(void); private: QPushButton *m_Btn; QLabel *m_Label; QWidget *m_MainWidget; }; #endif // WIDGET_H //widget.cpp [cpp] view plaincopyprint? #include "widget.h" Widget::Widget(QGraphicsItem *parent) : QGraphicsProxyWidget(parent) { m_MainWidget = new QWidget; m_Btn = new QPushButton(m_MainWidget); m_Label = new QLabel(m_MainWidget); m_Btn->setText("PushButton"); m_Btn->setGeometry(10, 10, 100, 30); m_Label->setGeometry(10, 40, 200, 30); QObject::connect(m_Btn, SIGNAL(clicked()), this, SIGNAL(sendOnButton())); setWidget(m_MainWidget); } Widget::~Widget() { delete m_MainWidget; } void Widget::changeText(const QString& s) { m_Label->setText(s); qDebug(" call Widget::changeText"); } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include #include "widget.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType("UIWidget", 1, 0, "Widget"); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); return a.exec(); } // UICtest.qml import Qt 4.7 import UIWidget 1.0 Rectangle { width: 640 height: 480 color: "black" Widget { id: uiwidget; x: 100; y: 100; width: 400; height: 100; // 关键在这里,当一个信号导出后他的相应的名字就是第1个字母大写,前面在加上on // 例如 clicked -- onClicked colorchange --onColorchange; onSendOnButton: { uiwidget.changeText(textinput.text); } } Rectangle{ x: 100; y: 20; width: 400; height: 30; color: "blue" TextInput {id: textinput; anchors.fill: parent; color: "white" } } } 说明: 这里实现的是当QPushButton按钮按下后,获取QML中TextInput上的文本, 对QLabel进行设置,关键点在于Widget中的信号函数sendOnButton, 他导出后在QML中 将引发的是onSendOnButton 只要在QML中对这个编写处理就可以实现,具体看代码。 QML与c++交互学习笔记(八) qt c++直接调用QML中的函数, 直接设置属性 1.这里主要是介绍,如何在c++中调用QML中的函数和设置QML中的属性的问题 2.具体代码 // UICtest.qml import Qt 4.7 Rectangle { id: mainWidget; width: 640 height: 480 function callbyc(v) { mainWidget.color = v; return "finish"; } Rectangle{ id: secondRect; x: 100; y: 20; width: 400; height: 300; Rectangle{ x: 10; y: 20; width: 30; height: 40; color: "#FF035721" Text { objectName: "NeedFindObj"; anchors.fill: parent; text: ""; } } } } // main.cpp [cpp] view plaincopyprint? #include #include #include #include #include #include #include int main(int argc, char *argv[]) { QApplication a(argc, argv); QDeclarativeView qmlView; qmlView.setSource(QUrl::fromLocalFile("../UICtest/UICtest.qml")); qmlView.show(); // 获取根节点,就是 QML中 id是mainWidget的节点 QDeclarativeItem *item = qobject_cast(qmlView.rootObject()); item->setProperty("color", QVariant("blue")); // 查找到我们需要的节点根均objectname NeedFindObj 来获得,并设置他的文本属性 QDeclarativeItem *item1 = item->findChild("NeedFindObj"); if (item1) { item1->setProperty("text", QVariant("OK")); } // 调用QML中的函数, 分别是 函数所在的对象, 函数名,返回值, 参数 QVariant returnVar; QVariant arg1 = "blue"; QMetaObject::invokeMethod(item, "callbyc", Q_RETURN_ARG(QVariant, returnVar),Q_ARG(QVariant, arg1)); qDebug(" %s",returnVar.toString().toLocal8Bit().data()); return a.exec(); } 说明: 这里的根节点是id为mainWidget的矩形元素,那么在C++中获取根节点后就可以,直接的设置他的属性了。其他属性也可以同样,调用指定节点内的函数是通过QMetaObject中的invokeMethod 来进行调用的。 |
|