您好,登錄后才能下訂單哦!
小編給大家分享一下C++程序中如何使用QML技術,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
在 C++程序中使用 QML
QML API 是分為三個主類——QDeclarativeEngine QdeclarativeComponent 與 QDecl arativeContext。QDeclarativeEngine 提供 QML 運行的環境QdeclarativeComponent 封 裝了 QML Documents 與 QDeclarativeCo
ntext 允許程序導出數據到 QML 組件實例。 QML 還包含了 API 的一個方便 通過 QDeclarativeView 應用程序只需要簡單嵌入 QML 組 件到一個新的 QGraphicsView 就可以了。這有許多細節將在下面討論。QDeclarativeView 主要是用于快速成型的應用程序里。 如果你是重新改進使用 QML 的 Qt 應用程序請參閱 整合 QML 到現有的 Qt UI 代碼。 基本用法 每個應用程序至少需求一個 QDeclarativeEngine。QDeclarativeEngine 允許配置全局設置 應用到所有的 QML 組件實例中 例如 QNetworkAccessManager 是用于網絡通信以及永久 儲存的路徑。如果應用程序需求在 QML 組件實例間需求不同的設置只需要多個 QDeclarati veEngine。 使用 QDeclarativeComponent 類載入 QML Documents。每個 QDeclarativeComponent 實例呈現單一 QML 文檔。 QDeclarativeComponent 可以傳遞一個文檔的地址或文檔的原始 文本內容。該文檔的 URL 可以是本地文件系統的地址或通過 QNetworkAccessManager 支 持的網絡地址。 QML 組件實例通過調用 QDeclarativeComponent::create()模式來創建。在這里載入一個 Q ML 文檔的示例并且從它這里創建一個對象。 QDeclarativeEngine *engine = new QDeclarativeEngine(parent); QDeclarativeComponent component(engine, QUrl::fromLocalFile(“main.qml”)); QObject *myObject = component.create();
導出數據 QML 組件是以 QDeclarativeContext 實例化的。context 允許應用程序導出數據到該 QML 組件實例中。 單個 QDeclarativeContext 可用于一應用程序的所有實例對象或針對每個實例 使用 QDeclarativeContext 可以創建更為精確的控制導出數據。如果不傳遞一個 context 給 QDeclarativeComponent::create()模式那么將使用 QDeclarativeEngine 的 root context。 數據導出通過該 root context 對所有對象實例是有效的。 簡單數據 為了導出數據到一個 QML 組件實例應用程序設置 Context 屬性然后由 QML 屬性綁定 的名稱與 JavaScrip 訪問。下面的例子顯示通過 QGraphicsView 如何導出一個背景顏色到
QML 文件中 //main.cpp #include <QApplication> #include <QDeclarativeView> #include <QDeclarativeContext>
int main(int argc, char *argv[]) { QApplication app(argc, argv);
QDeclarativeView view; QDeclarativeContext *context = view.rootContext(); context->setContextProperty(“backgroundColor”, QColor(Qt::yellow));
view.setSource(QUrl::fromLocalFile(“main.qml”)); view.show();
return app.exec(); }
//main.qml import Qt 4.7
Rectangle { width: 300 height: 300
color: backgroundColor
Text { anchors.centerIn: parent text: “Hello Yellow World!” } } 或者 如果你需要 main.cpp 不需要在 QDeclarativeView 顯示創建的組件 你就需要使用 Q DeclarativeEngine::rootContext()替代創建 QDeclarativeContext 實例。 QDeclarativeEngine engine; QDeclarativeContext *windowContext = new QDeclarativeContext(engine.rootContext ()); windowContext->setContextProperty(“backgroundColor”, QColor(Qt::yellow));
QDeclarativeComponent component(&engine, “main.qml”); QObject *window = component.create(windowContext);
Context 屬性的操作像 QML 綁定的標準屬性那樣——在這個例子中的 backgroundColor C ontext 屬性改變為紅色那么該組件對象實例將自動更新。注意刪除任意 QDeclarativeC
ontext 的構造是創建者的事情。當 window 組件實例撤消時不再需要 windowContext 時w indowContext 必須被消毀。最簡單的方法是確保它設置 window 作為 windowContext 的父 級。 QDeclarativeContexts 是樹形結構——除了 root context 每個 QDeclarativeContexts 都有 一個父級。子級 QDeclarativeContexts 有效的繼承它們父級的 context 屬性。這使應用程序 分隔不同數據導出到不同的 QML 對象實例有更多自由性。如果 QDeclarativeContext 設置 一 context 屬性同樣它父級也被影響新的 context 屬性是父級的影子。如下例子中ba ckground context 屬性是 Context 1也是 root context 里 background context 屬性的影 子。
結構化數據 context 屬性同樣可用于輸出結構化與寫數據到 QML 對象。除了 QVariant 支持所有已經存 在的類型外 QObject 派生類型可以分配給 context 屬性。 QObject context 屬性允許數據 結構化輸出并允許 QML 來設置值。 下例創建 CustomPalette 對象并設置它作為 palette context 屬性。 class CustomPalette : public QObject { Q_OBJECT Q_PROPERTY(QColor background READ background WRITE setBackground NOTIF Y backgroundChanged) Q_PROPERTY(QColor text READ text WRITE setText NOTIFY textChanged)
public: CustomPalette() : m_background(Qt::white), m_text(Qt::black) {}
QColor background() const { return m_background; } void setBackground(const QColor &c) { if (c != m_background) { m_background = c; emit backgroundChanged(); } }
QColor text() const { return m_text; } void setText(const QColor &c) { if (c != m_text) { m_text = c; emit textChanged(); } }
signals: void textChanged();
void backgroundChanged();
private: QColor m_background; QColor m_text; };
int main(int argc, char *argv[]) { QApplication app(argc, argv);
QDeclarativeView view; view.rootContext()->setContextProperty(“palette”, new CustomPalette);
view.setSource(QUrl::fromLocalFile(“main.qml”)); view.show();
return app.exec(); }
QML 引用 palette 對象以及它的屬性為了設置背景與文本的顏色這里是當單擊窗口時 面板的文本顏色將改變成藍色。 import Qt 4.7
Rectangle { width: 240 height: 320 color: palette.background
Text { anchors.centerIn: parent color: palette.text text: “Click me to change color!” }
MouseArea { anchors.fill: parent onClicked: { palette.text = “blue”; } } }
可以檢測一個 C++屬性值——這種情況下的 CustomPalette 的文本屬性改變該屬性必須 有相應的 NOTIFY 信息。NOTIFY 信號是屬性值改變時將指定一個信號發射。 實現者應該注意的是 只有值改變時才發射信號 以防止發生死循環。 訪問一個綁定的屬性
沒有 NOTIFY 信號的話將導致 QML 在運行時發出警告信息。 動態結構化數據 如果應用程序對結構化過于動態編譯 QObject 類型那么對動態結構化數據可在運行時使 用 QDeclarativePropertyMap 類構造。
從 QML 調用 C++ 通過 public slots 輸出模式或 Q_INVOKABLE 標記模式使它可以調用 QObject 派生出的類 型。 C++模式同樣可以有參數并且可以返回值。QML 支持如下類型 ?bool ?unsigned int, int ?float, double, qreal ?QString ?QUrl ?QColor ?QDate,QTime,QDateTime ?QPoint,QPointF ?QSize,QSizeF ?QRect,QRectF ?QVariant 下面例子演示了當 MouseArea 單擊時控制“Stopwatch”對象的開關。 //main.cpp class Stopwatch : public QObject { Q_OBJECT public: Stopwatch();
Q_INVOKABLE bool isRunning() const;
public slots: void start(); void stop();
private: bool m_running; };
int main(int argc, char *argv[]) { QApplication app(argc, argv);
QDeclarativeView view; view.rootContext()->setContextProperty(“stopwatch”, new Stopwatch);
view.setSource(QUrl::fromLocalFile(“main.qml”)); view.show();
return app.exec(); }
//main.qml
import Qt 4.7
Rectangle { width: 300 height: 300
MouseArea { anchors.fill: parent onClicked: { if (stopwatch.isRunning()) stopwatch.stop() else stopwatch.start(); } } }
值得注意的是在這個特殊的例子里有更好的方法來達到同樣的效果在 main.qml 有”run ning”屬性這將會是一個非常優秀的 QML 代碼 // main.qml import Qt 4.7
Rectangle {
MouseArea { anchors.fill: parent onClicked: stopwatch.running = !stopwatch.running } }
當然它同樣可以調用 functions declared in QML from C++。
網絡組件 如果 URL 傳遞給 QDeclarativeComponent 是一網絡資源或者 QML 文檔引用一網絡資源 QDeclarativeComponent 要先獲取網絡數據然后才可以創建對象。在這種情況下 QDecl arativeComponent 將有 Loading status。直到組件調用 QDeclarativeComponent::create() 之前應用程序將一直等待。 下面的例子顯示如何從一個網絡資源載入 QML 文件。在創建 QDeclarativeComponent 之 后它測試組件是否加載。如果是它連接 QDeclarativeComponent::statusChanged()信 號否則直接調用 continueLoading()。這個測試是必要的甚至 URL 都可以是遠程的只 是在這種情況下要防組件是被緩存的。 MyApplication::MyApplication() { // … component = new QDeclarativeComponent(engine, QUrl(“http://www.example.com/mai n.qml”)); if (component->isLoading()) QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Statu s)), this, SLOT(continueLoading())); else
continueLoading(); }
void MyApplication::continueLoading() { if (component->isError()) { qWarning() << component->errors(); } else { QObject *myObject = component->create(); } }
Qt 資源 QML 的內容可以使用 qrcURL 方案從 Qt 資源系統載入。例如 [project/example.qrc] <!DOCTYPE RCC> <RCC version=”1.0″>
<qresource prefix=”/”> <file>main.qml</file> <file>p_w_picpaths/background.png</file> </qresource>
</RCC>
[project/project.pro] QT += declarative
SOURCES += main.cpp RESOURCES += example.qrc
[project/main.cpp] int main(int argc, char *argv[]) { QApplication app(argc, argv);
QDeclarativeView view; view.setSource(QUrl(“qrc:/main.qml”)); view.show();
return app.exec(); } [project/main.qml] import Qt 4.7
Image { source: “p_w_picpaths/background.png” }
請注意資源系統是不能從 QML 直接訪問的。如果主 QML 文件被加載作為資源所有的 文件指定在 QML 中做為相對路徑從資源系統載入。 在 QML 層使用資源系統是完全透明的。 這也意味著如果主 QML 文件沒有被加載作為資源那么從 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 來進行調用的。 最后所有關于 QML 和 c++交互部分就基本寫完如果想要更多的東西或者一些其他方法強 烈看看 http://doc.qt.nokia.com/4.7-snapshot/qtbinding.html或者幫助文檔究竟是不是我的文檔里 面沒有還是怎么的
以上是“C++程序中如何使用QML技術”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。