Chinaunix首页 | 论坛 | 博客
  • 博客访问: 271693
  • 博文数量: 28
  • 博客积分: 290
  • 博客等级: 二等列兵
  • 技术积分: 326
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-10 12:12
文章分类

全部博文(28)

文章存档

2020年(1)

2018年(1)

2017年(3)

2015年(7)

2014年(9)

2010年(3)

2006年(4)

我的朋友

分类: C/C++

2015-02-01 11:22:56

 QQuickView是显示QtQuick用户界面的窗口。 它的基类是QQuickWindow,通过指定qml源文件的路径自动加载和显示QML场景。另一种方法是使用QQuickWindow和QQmlComponent配合加载QML。
QQuickView *view = new QQuickView;
view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
view->show();
通过元对象系统的交互, QML引擎可以直接访问QObject类的所有功能。
Properties
Methods (必须是public slots或者标记为Q_INVOKABLE)
Signals
如果要把QObject类作为数据类型使用时,必须注册为QML类型,例如:把该类或该类的枚举作为信号参数或方法参数和返回值以及声明为属性

暴露属性到QML
1.使用宏Q_PROPERTY()可以为任何QObject类指定属性。属性是类的数据成员,有一个关联的读函数,一个关联的写函数和值变化信号。QML通过属性和它的关联函数访问QObject类中的数据成员
class Message : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
public:
    void setAuthor(const QString &a) {
        if (a != m_author) {
            m_author = a;
            emit authorChanged();
        }
    }
    QString author() const {
        return m_author;
    }
signals:
    void authorChanged();
private:
    QString m_author;
};

2.创建QML运行时,把这个类的一个对象设置为QML引擎上下文的属性:
 int main(int argc, char *argv[]) {
     QCoreApplication app(argc, argv);
     QQmlEngine engine;
     Message msg;
     engine.rootContext()->setContextProperty("msg", &msg);
     QQmlComponent component(&engine, QUrl::fromLocalFile("MyItem.qml"));
     component.create();
     return app.exec();
 }

3.在QML代码中读写这个对象的属性
// MyItem.qml
import QtQuick 2.0
Text {
    width: 100; height: 100
    text: msg.author    // invokes Message::author() to get this value
    Component.onCompleted: {
        msg.author = "Jonah"  // invokes Message::setAuthor()
    }
}
为了与最大化地与QML整合,任何可写的属性都要有一个与其关联的NOTIFY信号。属性值发生改变时,信号发送。这允许该属性可以用于属性绑定。

暴露方法到QML
1.通过以下两种方式把QObject类任何方法暴露到QML代码。
    使用宏Q_INVOKABLE()标记公共方法
    把方法声明为公共槽函数 public slots
 class MessageBoard : public QObject
 {
     Q_OBJECT
 public:
     Q_INVOKABLE bool postMessage(const QString &msg) {
         qDebug() << "Called the C++ method with" << msg;
         return true;
     }
 public slots:
     void refresh() {
         qDebug() << "Called the C++ slot";
     }
 };

2.创建QML运行时,把这个类的一个对象设置为QML引擎上下文的属性:
 int main(int argc, char *argv[]) {
     QGuiApplication app(argc, argv);
     MessageBoard msgBoard;
     QQuickView view;
     view.engine()->rootContext()->setContextProperty("msgBoard", &msgBoard);
     view.setSource(QUrl::fromLocalFile("MyItem.qml"));
     view.show();
     return app.exec();
 }

3.在QML代码中读写这个对象的方法:
// MyItem.qml
import QtQuick 2.0
Item {
    width: 100; height: 100
    MouseArea {
        anchors.fill: parent
        onClicked: {
            var result = msgBoard.postMessage("Hello from QML")
            console.log("Result of postMessage():", result)
            msgBoard.refresh();
        }
    }
}
如果C++方法有QObject类型的参数时,在QML代码使用对象ID或var值来完成参数传递。

暴露信号到QML
1.QML引擎会为QObject类型的任何信号自动创建信号处理器。on是信号处理器的名字,其中Signal是信号的名字。信号处理器通过信号的参数名字来处理传递过来的参数。
 class MessageBoard : public QObject
 {
     Q_OBJECT
 public:
    // ...
 signals:
    void newMessagePosted(const QString &subject);
 };

2.把MessageBoard注册为QML的类型后才能用于声明MessageBoard对象,使用信号处理器onNewMessagePosted来处理newMessagePosted()的信号。
MessageBoard {
    onNewMessagePosted: console.log("New message received:", subject)
}
信号参数的类型与方法参数和属性的类型一样,都必须是QML引擎支持的类型。

如果不想把C++对象注册为QML类型,还可以使用connection对象响应C++信号。
Connections {
    target: MessageBoard 
    onNewMessagePosted: console.log("New message received:", subject)
}

阅读(7677) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~