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方法中更新其他属性。

时间: 2024-11-07 15:43:25

Qt Quick快速入门之qml与C++交互的相关文章

Qt Quick快速入门之qml布局

Qml里面布局主要有两种,锚点布局.Grid布局. 锚点布局使用anchors附件属性将一个元素的边定位到另一个元素的边,从而确定元素的位置和大小.下面是示例 1 import QtQuick 2.3 2 import QtQuick.Window 2.0 3 4 Window { 5 id:anchorLayoutWindow; 6 width: 480; 7 height: 320; 8 title: "AnchorLayout"; 9 10 Rectangle{ 11 id:re

Qt Quick快速入门

年前花了一个多月的时间看Qt的文档并根据自己的需要演练了一部分,之后写了一套UI,然后陆陆续续也弄了一些小工具(主要是上位机程序),由于后面工作估计会越来越忙,就能写一点是一点了,希望能对读者有帮助. 1.Qt Quick快速入门之qml布局 2.Qt Quick快速入门之qml与C++交互 3.Qt Quick快速入门之信号.槽 4.Qt Quick快速入门之线程基础 5.Qt Quick自定义样式一套 顺便打个广告,公司最近要补充一大批人(貌似要招差不多100人左右吧,研发方面主要是硬件.嵌

Qt Quick快速入门之线程基础

首先必须明确的是,Qt中的线程使用是相对复杂的,并不像C#中那么随意,特别是结合串口.网络编程等,使用时稍有不慎就会出问题,然后Qt里面经常出了问题就直接崩溃(这个真是谁用谁知道),所以如果在功能上用异步方式能做到其实就没必要自己去开线程,当然如果自己写的函数比较耗时(比如不断地循环做操作之类的)就无法避免使用线程了. Qt中一般将耗时操作单独放在一个类中实现,在主线程中创建类对象,然后将这个对象移到子线程中,主线程与子线程间的通信主要通过信号和槽实现.另外对象是在主线程中创建的,对象中的成员都

Qt Quick快速入门之信号、槽

信号和槽主要用于组件之间的通信,类似于.net和java中的委托. 使用QObject::connect方法将信号与槽关联起来,然后信号的发起者发出信号,接受者中的槽函数就会执行. 比如connect(this,SIGNAL(start()),worker,SLOT(Start())),将当前类中start信号关联到worker对象的Start函数,当我们调用emit this->start()时就发出信号,槽函数就会收到这个信号. connect函数还有第五个参数,这个参数决定信号何时传给槽,

Qt 动画快速入门(一)

Qt-4.6动画Animation快速入门三字决 Qt-4.6新增了Animation Framework(动画框架),让我们能够方便的写一些生动的程序.不必像以前的版本一样,所有的控件都枯燥的呆在伟大光荣的QLayout里,也许它们可以唱个歌,跳个舞.    所谓动画就是在一个时间段内的不同时间点有不同的状态,只要定义好这样状态,实现动画就是水到渠成的事情.当然做这件事情,最好用的就是状态机,没错Qt-4.6.0提供了QStateMachine类,不过今天我要讲的三字决要简单一些. 第一决:Q

从头学Qt Quick(2)-- QML语法从一个简单的例子说起

在上一篇文章中,我们对QtQuick做了简单的介绍,体验了使用QML语言构建一个UI的便捷.这里我们简要介绍一下QML的语法. QML将界面分成一些更小的元素,这些元素可以组成一个组件,QML语言描述了UI的形状和行为,并且可以使用JavaScript修饰.总的来说QML的结构有点像HTML,其语法和CSS比较近似. 1.QML层次结构 要使用QML进行界面的布局,首先需要理解QML元素的层次结构.QML的层次结构很简单,是一个树形结构,最外层必须有一个根元素,根元素里面可以嵌套一个或多个子元素

[Qt Creator 快速入门] 第5章 应用程序主窗口

??这一章开始接触应用程序主窗口的相关内容.对于日常见到的应用程序而言,许多都是基于主窗口的,主窗口中包含了菜单栏.工具栏.状态栏和中心区域等.这一章会详细介绍主窗口的每一个部分,还会涉及资源管理.富文本处理.拖放操作和文档打印等相关内容.重点是讲解知识点,而相关的综合应用实例放到了<Qt及Qt Quick开发实战精解>一书中. ??Qt中提供了以QMainWindow类为核心的主窗口框架,包含了众多相关的类,它 们的继承关系如图5 - 1所示,本章会讲解到图中每一个类的基本应用. 图5-1主

QT Creator 快速入门教程 读书笔记(一)

一 Qt简介 Qt 是一个跨平台的C++应用程序框架,支持Windows.Linux.Mac OS X.Android.iOS.Windows Phone.嵌入式系统等.也就是说,Qt 可以同时支持桌面应用程序开发.嵌入式开发和移动开发,覆盖了现有的所有主流平台.你只需要编写一次代码,发布到不同平台前重新编译即可. Qt 不仅仅是一个GUI库,它除了可以创建漂亮的界面,还有很多其他组件,例如,你不再需要研究STL,不再需要C++的<string>头文件,不再需要去找解析XML.连接数据库.So

[Qt Creator 快速入门] 第8章 界面外观

??一个完善的应用程序不仅应该有实用的功能,还要有一个漂亮的外观,这样才能使应用程序更加友好,更加吸引用户.作为一个跨平台的UI开发框架,Qt提供了强大而灵活的界面外观设计机制.这一章将学习在Qt中设计应用程序外观的相关知识,会对Qt 风格QStyle和调色板QPalette进行简单介绍,然后再对Qt样式表(Qt Style Sheets)进行重点讲解,最后还会涉及了不规则窗体和透明窗体的实现方法. 8.1 Qt风格 ??Qt中的各种风格是一组继承自QStyle的类.QStyle类是一个抽象基类