QML与C++交互



  • 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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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

    #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++交互学习笔记(八) qtc++直接调用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

    #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();  
    }  
    

    说明:

    这里的根节点是id为mainWidget的矩形元素,那么在C++中获取根节点后就可以,直接的设置他的属性了。其他属性也可以同样,调用指定节点内的函数是通过QMetaObject中的invokeMethod 来进行调用的。


  • 嗯,是好文章呢。可不可以将它放在博客区呢?



  • ...Nice...



  • 好东西,交互我一直不懂,马了等不忙再看



  • @_Inky 对了,如果是Qt 5,具体来说是Qt 5.1以后,那么这么写是不能通过的。很多地方都要换成QQuick*。import Qt 4.7 ——Qt 5以后的版本使用的是import QtQuick 2.5



  • 问个问题,我在widget生成的界面中调用qml生成的界面;采用qtquick1.0,通过declarative可以正常显示;不过目前我要使用qtquick2.0,调用中提示Can't find surface 2 ,版主知道什么原因不?O(∩_∩)O谢谢

    注:在main.cpp中直接调用qml无论qtquick是1.0还是2.0都可以正常显示。
    0_1451025835488_upload-595f92da-63b9-4ac8-aca6-9a9a3af17476



  • @Eli 这个view的Parent设置为mainWindow的指针试试看?



  • @jiangcaiyang 你好楼主,有没有办法在c++导出的类型中写入qml基本组件,例如写一个Rectangle,我写完它不显示,因为之前做的东西里他们就是这么写的可现在我自己实现不会写了感觉。例如笔记一里你导出了Person类,然后在qml中直接写Person{
    Rectangle{}
    }// 有没有可以这样写的方法。



  • @jiangcaiyang 😐 谢谢指正


Log in to reply
 

走马观花

最近的回复

  • C

    Qt for MCU需要商业授权的

    read more
  • Qt for MCUs

    搭建Qt for MCUs PC端开发环境。qt for mcus提供了一个完整的图形框架和工具包,包含了在MCUs上设计、开发和部署gui所需的一切。它允许您在裸机或实时操作系统上运行应用程序。

    先决条件

    开发主机环境支持仅限于Windows 10

    MSVC compiler v19.16 (Visual Studio 2017 15.9.9 or newer) x64

    CMake v3.13 or newer (you can install it using the Qt Online installer) x64

    使用Qt联机安装程序安装Qt for MCUs,该安装程序可通过Qt帐户下载

    安装Qt 5.14和Qt Creator 4.11 or higher

    安装链接

    › Qt: https://account.qt.io/downloads
    › CMake: https://cmake.org/download/
    › Python 2.7 32-bit: https://www.python.org/downloads/release/python-2716/
    › Arm GCC: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnutoolchain/gnu-rm/downloads
    › J-Link Software Pack: https://www.segger.com/downloads/jlink/JLink_Windows.exe
    › J-Link OpenSDA Firmware: https://www.segger.com/downloads/jlink/OpenSDA_MIMXRT1050-EVKHyperflash
    › STM32CubeProgrammer: https://www.st.com/en/development-tools/stm32cubeprog.html
    › STM32 ST-LINK Utility: https://www.st.com/en/development-tools/stsw-link004.html​​​​​​​

    Qt Creator设置 启用Qt Creator插件 选择“帮助>关于插件”,然后从列表中选择“MCU支持(实验性)”插件,重新启动Qt Creator以应用更改
    替代文字 为MCU创建Qt工具包

    选择工具>选项>设备>MCU

    选择Qt for MCUs-Desktop 32bpp作为目标

    如果尚未设置,请提供Qt for MCUs安装目录的路径。

    单击Apply应用。

    替代文字

    替代文字
    替代文字

    注意:

    编译器要选X64,Qt版本要选64bit,CMake Tool选x64

    打开恒温器项目demo

    选择文件>打开文件或项目。。。

    打开CMakefiles.txt文件来自thermo文件夹的文件。

    选择Qt作为MCU-桌面32bpp套件。

    单击“配置项目”以完成。

    替代文字

    问题

    开发主机环境支持仅限于Windows 10

    C++编译失败,文本大字体.pixelSize.

    文本类型无法正确呈现需要复杂文本布局的unicode序列。对复杂文本使用StaticText

    read more
  • H

    hi 有问题请教你,方便加个联系方式吗

    read more
  • boost.asio是一个很棒的网络库,这回儿我也开始系统地学习起来了。想想当年接触boost,也有八年多了。这次开始接触boost,觉得既熟悉又陌生。熟悉的是小写字母+下划线的命名方式、晦涩的模板、很慢的编译速度以及较大的程序体积,陌生的是asio的各种概念:io服务、接收器、套接字等等:我之前对网络编程不是非常了解。

    于是根据我的理解,参考《Boost.Asio C++网络编程》实现了这样一个简单的客户端和服务端通信的例子,例子非常简单,还不完善,但是幸运的是,可以在本机上互通了。
    下面是客户端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void writeHandler( const boost::system::error_code& ec, size_t bytesTransferred ) { if ( ec ) { cout << "Write data error, code: " << ec.value( ) << "transferred: " << bytesTransferred << endl; } else { cout << "OK! " << bytesTransferred << "bytes written. " << endl; } } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::socket sock( service ); ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; sock.connect( ep, ec ); if ( ec ) { cout << "Connect error, code: " << ec.value( ) << ", We will exit." << endl; return ec.value( ); } else { char buf[1024] = "Hello world!"; sock.async_write_some( buffer( buf ), writeHandler ); sock.close( ); } return service.run( ); }

    下面是服务端的代码:

    #include <iostream> #include <boost/asio.hpp> #include <boost/proto/detail/ignore_unused.hpp> using namespace std; using namespace boost::asio; using namespace boost::system; using namespace boost::proto::detail;// 提供ignore_unused方法 void acceptHandle( const boost::system::error_code& code ) { cout << "Accepted." << endl; } int main(int argc, char *argv[]) { ignore_unused( argc ); ignore_unused( argv ); io_service service; ip::tcp::endpoint ep( ip::address::from_string( "127.0.0.1" ), 6545 ); boost::system::error_code ec; ip::tcp::socket sock( service ); ip::tcp::acceptor acceptor( service, ep ); acceptor.async_accept( sock, acceptHandle ); if ( ec ) { cout << "There is an error in server. code: " << ec.value( ) << endl; } return service.run( );// 阻塞运行 }

    运行结果是这样的:
    78448d7b-b3ae-42fc-9e2e-4dd2fbdac2c2-image.png

    我对boost.asio中几个概念的理解:

    io_service,这就是一个类似事件循环的东西,它为io设备提供服务,故名。不管是套接字、文件还是串口设备,都要使用它的服务。它的run()函数相当于启动了一个事件循环。一旦有消息了,即进行响应。这也是实现异步编程的重要基础。 socket,这个类则是套接字,可以处理TCP或者是UDP请求。有同步以及异步的处理方式,也有带异常以及不带异常的处理方式。 acceptor,接收器,仅仅是服务端使用。相当于其余框架中的listener,作接收用的。

    比较浅显,如果有不当之处,敬请指正。

    read more

关注我们

微博
QQ群