QML與c++交互學習筆記(一)
說明,主要是對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 plain copy#ifndef PERSON_H #define PERSON_H #include <QObject> 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 plain copy#include <QtGui/Qapplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType<Person>("People",1,0,"Person"); //qmlRegisterType<Person>(); 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<Person>(); 導出就可以注釋這條 Rectangle { width: 640 height: 480 Person{} } |
說明:我們通過qmlRegisterType<Person>("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 plain copy#ifndef PERSON_H #define PERSON_H #include <QObject> 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 plain copy#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 plain copy#include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType<Person>("People",1,0,"Person"); //qmlRegisterType<Person>(); 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<Person>(); 導出就可以注釋這條 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 plain copy#ifndef PERSON_H #define PERSON_H #include <QObject> #include <QColor> 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 plain copy#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 plain copy#include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType<Person>("People",1,0,"Person"); //qmlRegisterType<Person>(); 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<Person>(); 導出就可以注釋這條 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 plain copy#ifndef PERSON_H #define PERSON_H #include <QObject> #include <QColor> 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 plain copy#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 plain copy#include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType<Person>("People",1,0,"Person"); //qmlRegisterType<Person>(); qmlRegisterType<Job>("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<Person>(); 導出就可以注釋這條 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 plain copy#ifndef PERSON_H #define PERSON_H #include <QObject> #include <QDeclarativeListProperty> #include <QList> 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(QDeclarativeListProperty<Person> members READ members) public: explicit PersonGroup(QObject *parent = 0); QDeclarativeListProperty<Person> members(void); Q_INVOKABLE int membersCount(void) const; Q_INVOKABLE Person *member(int index) const; private: QList<Person*> m_MemberList; }; #endif // PERSON_H |
// person.cpp [cpp] view plain copy#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) { } //--------------------------------- // QDeclarativeListProperty<Person> PersonGroup::members(void) { return QDeclarativeListProperty<Person>(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 plain copy#include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include "person.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType<Person>("People",1,0,"Person"); //qmlRegisterType<Person>(); qmlRegisterType<PersonGroup>("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<Person>(); 導出就可以注釋這條 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 plain copy#ifndef PERSON_H #define PERSON_H #include <QObject> #include <QDeclarativeListProperty> #include <QList> #include <QColor> 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 plain copy#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 plain copy#include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include <QtDeclarative/QDeclarativeContext> #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.nokia.com/4.7-snapshot/qtbinding.html
2.具體代碼
//widget.h [cpp] view plain copy#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QGraphicsProxyWidget> #include <QPushButton> #include <QLabel> #include <QLineEdit> 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 plain copy#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 plain copy#include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include <QtDeclarative/QDeclarativeContext> #include "widget.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); qmlRegisterType<Widget>("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 plain copy#include <QtGui/QApplication> #include <QtDeclarative/QDeclarativeView> #include <QtDeclarative/QDeclarativeEngine> #include <QtDeclarative/QDeclarativeComponent> #include <QtDeclarative/QDeclarativeContext> #include <QtDeclarative/QDeclarativeItem> #include <QMetaObject> 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<QDeclarativeItem*>(qmlView.rootObject()); item->setProperty("color", QVariant("blue")); // 查找到我們需要的節點根均objectname NeedFindObj 來獲得,并設置他的文本屬性 QDeclarativeItem *item1 = item->findChild<QDeclarativeItem *>("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(); }![]() |
新聞熱點
疑難解答
圖片精選