Qt Quick快速入門之qml與C++交互


  C++中使用qml對象,直接使用findChild獲取qml對象,然后調用setProperty方法設置屬性,當然必須在加載qml之后才能使用,不然findChild找不到對象,用法如下。

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    QObject * text_Msg = engine.rootObjects()[0]->findChild<QObject*>("text_Msg");
    text_Msg->setProperty("color","red");

 

  qml使用C++對象,這也是Qt中Model/View的實現方法,下面是一個例子。

  首先,類需要繼承自QObejct

class User:public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString Name READ Name WRITE setName NOTIFY NameChanged)
    Q_PROPERTY(int Age READ Age WRITE setAge NOTIFY AgeChanged)
    Q_PROPERTY(QString Message READ Message WRITE setMessage NOTIFY MessageChanged)
public:
    User();
    User(string name,int age);

    QString Name();
    void setName(QString name);

    int Age();
    void setAge(int age);

    QString Message();
    void setMessage(QString message);
signals:
    void NameChanged();
    void AgeChanged();
    void MessageChanged();
public slots:
void editOk();    

private :
    QString m_name;
    int m_age;
    QString m_message;
};

  

User::User()
{
  this->setName("");
  this->setAge(0);
}
User::User(string name, int age)
{
  QString q_name = QString::fromStdString(name);
  this->setName(q_name);
  this->setAge(age);
}

QString User::Name()
{
  return m_name;
}
void User::setName(QString name)
{
  m_name = name;
  emit NameChanged();
  setMessage(QString("名稱改變為:%1").arg(name));
}

int User::Age()
{
  return m_age;
}
void User::setAge(int age)
{
  m_age = age;
  emit AgeChanged();
  setMessage(QString("年齡改變為:%1").arg(age));
}

QString User::Message()
{
    return m_message;
}

void User::setMessage(QString message)
{
    m_message = message;
    emit MessageChanged();
}
void User::editOk()
{
    setMessage("您點擊了確定按鈕");
}

   然后,需要向qml中注冊這個類,這樣我們在qml中就可以導入這個類了

qmlRegisterType<User>("Models.User",1,0,"UserModel");

  

import Models.User 1.0

  通常,直接將對象設置到qml對象的上下文,然后在qml中使用C++對象的屬性

    QQmlApplicationEngine engine;
    QQmlContext* context = engine.rootContext();
    User* userModel = new User("測試",20);
    context->setContextProperty("testUserModel",userModel);
GridLayout{
        anchors.centerIn: parent
        width:300
        columnSpacing: 10
        rowSpacing: 10
        rows:4
        columns:2

        Item{
            Layout.row: 0
            Layout.column: 0
            width:100
            height:30
            Text{
                text:"Name:"
                anchors.centerIn: parent
            }
        }
        Item{
            Layout.row: 0
            Layout.column: 1
            Layout.fillWidth: true
            height:30
            TextField{
                anchors.verticalCenter: parent.verticalCenter
                width:parent.width
                height:24
                id:textfield_Name
                text: testUserModel.Name
                onEditingFinished: {
                    testUserModel.Name = textfield_Name.text;
                }
            }
        }

        Item{
            Layout.row: 1
            Layout.column: 0
            width:100
            height:30
            Text{
                text:"Age:"
                anchors.centerIn: parent
            }
        }
        Item{
            Layout.row: 1
            Layout.column: 1
            Layout.fillWidth: true
            height:30
            TextField{
                anchors.verticalCenter: parent.verticalCenter
                width:parent.width
                height:24
                id:textfield_Age
                text:testUserModel.Age
                onEditingFinished: {
                    testUserModel.Age = textfield_Age.text;
                }
            }
        }

        Item{
            Layout.row: 2
            Layout.column: 0
            Layout.fillWidth: true
            height: 50
            Layout.columnSpan: 2
            RowLayout{
                anchors.centerIn: parent
                Button{
                    id:button_OK
                    text:"確定"
                    action: button_OK_Action
                    onClicked:{
                        testUserModel.editOk();
                    }
                }
                Button{
                    id:button_Cancel
                    text:"取消"
                    onClicked: {
                        Qt.quit();
                    }
                }
            }
        }

        Item{
            Layout.row: 3
            Layout.column: 0
            Layout.fillWidth: true
            height: 30
            Layout.columnSpan: 2
            Text {
                id: text_Msg
                objectName: "text_Msg"
                text: testUserModel.Message
                anchors.fill: parent
                verticalAlignment: Qt.AlignVCenter
            }
        }

    }

  在qml中綁定C++對象的屬性時,其實是執行C++對象屬性的READ方法;而設置屬性時,則是執行WRITE方法;C++屬性的NOTIFY方法用於屬性變更通知,當我們調用該方法時(通常在前面加上emit表示這是個信號方法),qml中的屬性綁定就會再次執行READ方法。

  下面是效果,編輯框失去焦點時,就會設置屬性,進而調用C++對象的WRITE方法,然后在WRITE方法中更新其他屬性。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM