Qt Quick快速入门之qml与C++交互

时间:2023-03-09 08:04:40
Qt Quick快速入门之qml与C++交互

  C++中使用qml对象,直接使用findChild获取qml对象,然后调用setProperty方法设置属性,当然必须在加载qml之后才能使用,不然findChild找不到对象,用法如下。

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject * text_Msg = engine.rootObjects()[]->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();
}
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",,,"UserModel");

  

import Models.User 1.0

  通常,直接将对象设置到qml对象的上下文,然后在qml中使用C++对象的属性

    QQmlApplicationEngine engine;
QQmlContext* context = engine.rootContext();
User* userModel = new User("测试",);
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方法中更新其他属性。

Qt Quick快速入门之qml与C++交互