Qt實用技巧:在Qt Gui程序中嵌入qml界面(可動態覆蓋整個窗口)

若該文爲原創文章,未經允許不得轉載
原博主博客地址:http://blog.csdn.net/qq21497936
原博主博客導航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78486552
各位讀者,知識無窮而人力有窮,要麼改需求,要麼找專業人士,要麼自己研究

紅胖子(紅模仿)的博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬結合等等)持續更新中…(點擊傳送門)

 

Qt開發專欄:實用技巧(點擊傳送門)

 

前話

        使用qml做界面比使用qtgui強大很多,當然內存使用增大,效率降低是無法避免的,各有取捨,一般在電腦上跑的使用qml也基本無壓力吧,當然具體情況具體分析。

需求

        跨入qml,需要做一系列動畫,考慮將qml與qwidget結合起來,所以首先要做的是:

        1.如何將qml嵌入qwidget中;

        2.如何將動態更改qml窗口的大小;

原理

        將qml嵌入式到qwidget中,qt4與qt5方法有很大區別,本人使用的qt5.2;

        通過創建窗口容器的方法QWidget::createWindowContainer()將qml嵌入式qwidget,傳遞值使用setContextProperty()方法;

入坑

        1.設置qml交互屬性的時候,設置一次交互屬性值,纔會更新一次,所以要主動重新設置屬性一次,在resizeEvent()中,每次改變都設置

        2.在設置根Rectangle的時候,經過測試發現width和height可決定QuickWidget的寬度和高度,實際操作過程中width和height變大時,實際效果未變大,未變大的原因是因爲Rectangle的width和height超過了QQuickWidget的width和height,即超出了QucikWidget的顯示範圍,所以顯示不出;

        3.QuickWidget若沒有qml的元素部分,默認背景是白色的;

特性

        qml的根窗口的0,0永遠是其qwdiget的右上角;

        qml中的子控件的座標永遠是相對其父的右上角的座標;

        qml根Rectangle,若不設置高度和寬度,那麼第一次默認顯示爲全窗口,當動態調節主窗口(嵌入式qml的窗口)時,qml的窗口大小不會更改,需要手動;

 

代碼

第一部分:./qml/start.qml代碼 

 

import QtQuick 2.0

Rectangle {
    x: 0; // 缺省爲0
    y: 0; // 缺省爲0
    width: quickWidgetWidth;   // width是寬度
    height: quickWidgetHeight; // height是高度
    color: "red";
}

 

第二部分:將qml嵌入qwidget代碼(包含改變窗口大小時,qml大小適配)

 

void MainWindow::initQmlWidget()
{
    qDebug() << __FILE__ << __LINE__ << rect() << geometry();
    // 初始化quick窗口
    _pQuickView = new QQuickView();
    _pQuickView->setSource(QUrl("./qml/start.qml"));
    _pQuickWidget = QWidget::createWindowContainer(_pQuickView, this);
    // 用於與qml交互
    _pQmlContext = _pQuickView->rootContext();
    // 顯示qml
    _pQuickWidget->show();
}

void MainWindow::resizeEvent(QResizeEvent *e)
{
    // 設置 QQuickWidget 窗口大小
    _pQuickWidget->setGeometry(rect());
    // 設置 將qml中的rectangle屬性值,使rectangle鋪滿QQuickWidget,而QQucikWidget設置爲鋪滿主窗口
    _pQmlContext->setContextProperty("quickWidgetWidth", rect().width());
    _pQmlContext->setContextProperty("quickWidgetHeight", rect().height());
}

 

效果

 

拓展1

        可以將qml的qwidget窗口所在的父窗口設置爲,無邊框,代碼如下

 

    // 設置無邊框
    setWindowFlags(windowFlags() | Qt::FramelessWindowHint);

 

拓展1效果

拓展2

        在一個qml中,根對象只有一個,那麼如何顯示多個rectange呢,使用Item對象作爲根對象,無法改變背景顏色;

 

import QtQuick 2.0

Item
{
    Rectangle {
        x: 0;
        y: 0;
        width: 200;   // 根據主窗口寬度改變
        height: 200; // 根據主窗口高度改變
        color: 'yellow';
        Text {
            anchors.centerIn: parent;
            text: 'hello world!';
        }
    }

    Rectangle {
        x:300
        y:300
        width: 200;
        height: 200;
        color: "red";
    }
}

 

拓展2效果

拓展3

        實現背景,實現透明

 

import QtQuick 2.0

Item
{
    Rectangle {

        width: quickWidgetWidth;
        height: quickWidgetHeight;
        color: "black";
        Rectangle {
            x: 0;
            y: 0;
            width: 200;
            height: 200;
            color: 'yellow';
            Text {
                anchors.centerIn: parent;
                text: 'hello world!';
            }
            z: 1; // 堆疊順序,越大越在上面
        }

        Rectangle {
            x:150
            y:150
            width: 200;
            height: 200;
            color: "red";
            opacity: 0.6 // 透明度,會疊加在父類上
            z: 0; // 堆疊順序,越大越在上面
        }
        opacity: 0.8; // 透明度
    }
}

 

拓展3效果

 

原博主博客地址:http://blog.csdn.net/qq21497936
原博主博客導航:http://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78486552

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章