QT qml定制炫酷界面--Apple的學(xué)習(xí)筆記

一,前言

上次QT GraphicsItem GUI界面定制--Apple的學(xué)習(xí)筆記中我已經(jīng)研究了下graphicsview,能進(jìn)行簡(jiǎn)單的自定義對(duì)象界面。但是卡住我的就是那個(gè)layout界面是window style的,怎么修改風(fēng)格呢?于是我開(kāi)始研究關(guān)鍵炫酷界面定制,了解到了以前QT會(huì)用CSS,后來(lái)有了paint重繪,比如基于graphicsview的界面,然后現(xiàn)在主推的是邏輯與界面分離的設(shè)計(jì),也就是主推qml編程。

二,grapicsItem組合炫酷界面

這3者這幾天我都簡(jiǎn)單玩了下。先用我熟悉的graphicview制作了類似ue4的藍(lán)圖界面元素。現(xiàn)在卡住我的依然是捆綁方案。
方案1:我用了graphicsItem里面添加了qwidget的txt元素。
方案2:和方案1類似的思路是用graphicsTextItem綁定到自定義的item中。
方案3:用QGraphicsItemGroup來(lái)綁定2個(gè)對(duì)象,讓QGraphicsItemGroup升級(jí)為我的自定義對(duì)象。
但是這些方案中都有一個(gè)問(wèn)題就是click txt后無(wú)法編輯。這個(gè)查看了下是關(guān)于鼠標(biāo)事件透?jìng)?,網(wǎng)上說(shuō)要設(shè)置屬性,然后設(shè)置為透?jìng)?,關(guān)于每個(gè)回調(diào)函數(shù)調(diào)用的順序我還搞的不是很清楚。但是個(gè)人覺(jué)得第3種方案會(huì)比較好。
我先用graphicsView來(lái)繪制了炫酷界面
其實(shí)界面的設(shè)計(jì)參考了python的Ryven及ue4藍(lán)圖界面風(fēng)格。我自定義一個(gè)graphicsItem類如下


image.png

關(guān)于這個(gè)界面的源碼,需要的同學(xué)可以聯(lián)系我。

三,基于qml的炫酷界面

簡(jiǎn)單學(xué)了下qml語(yǔ)法及查看qml help的方法后,入門qml真的很快。而且發(fā)現(xiàn)它比graphicsItem用起來(lái)簡(jiǎn)單多了,qml其實(shí)主推的是和js配套使用,一個(gè)做前臺(tái)界面美化,一個(gè)做后臺(tái)功能邏輯。
qml我可以做一個(gè)自定義的對(duì)象,然后qml里面也解決了多重對(duì)象鼠標(biāo)事件透?jìng)鳎枰O(shè)置propagateComposedEvents: true,但是關(guān)于組合體的布局我沒(méi)有用錨,而是固定的直接坐標(biāo),這個(gè)不太好。
qml已經(jīng)實(shí)現(xiàn)了炫酷界面定期,內(nèi)嵌的txt文本編輯庫(kù)可以在鼠標(biāo)左鍵/右擊/左鍵+shift鍵的時(shí)候更改文本內(nèi)容。然后也可以拖動(dòng)。算是完成了簡(jiǎn)單的HMI定制功能。

qml炫酷界面.gif

四,qml源碼

image.png
  1. main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
#if 0
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
#endif
    return app.exec();
}

main.qml

import QtQuick 2.15
import QtQuick.Window 2.15

Window {
    id:mainRoot
    width: 300
    height: 200
    visible: true
    title: qsTr("Apple Leaning")
    Customitem{
        //anchors.fill: parent
    }

}

Customitem.qml

import QtQuick 2.0
Item
{
    // 背景
    Rectangle {
        id: myobj
        x: 0; y: 0
        width: 120; height: 160
        color: "black"
        radius: 5
        border.color: "red"
        border.width: 2
        //  標(biāo)題
        Rectangle {
            id: objtytle
            x: 0; y: 0
            radius: 5
            width: 120; height: 32
            border.width:1
            border.color:"red"
            smooth:true
            gradient: Gradient{
                GradientStop{position: 0.0; color: "black"}
                GradientStop{position: 1.0; color: "red"}
            }
            //rotation: 90
            transformOrigin: "Center"

            Text{
                text: "Apple's Demo"
                color:"#e26161"
                anchors.centerIn: parent
            }
        }
        //第一個(gè)輸入口
        Rectangle {
            x: 10;y:40
            width: 16    //width
            height: 16   //=width
            //color: Qt.rgba(200/255,0/255,0/255, 0.5)
            color: "black"
            radius: 8   //width/2
            border.color: "red"

            Canvas {
                id: canvasId1
                x:17;y:2
                property color triangleColor: "#474747"
                width: 8; height: 12
                contextType: "2d"
                onPaint: {
                    context.lineWidth = 0
                    context.strokeStyle = "#00000000"
                    context.fillStyle = triangleColor
                    context.beginPath();
                    context.moveTo(0, 0)
                    context.lineTo(0, canvasId1.height);
                    context.lineTo(canvasId1.width, canvasId1.height/2);
                    context.closePath();
                    context.fill()
                    context.stroke();
                }
            }

        }

        //第二個(gè)輸入口
        Rectangle {
            x: 10;y:70
            width: 16    //width
            height: 16   //=width
            //color: Qt.rgba(200/255,0/255,0/255, 0.5)
            color: "black"
            radius: 8   //width/2
            border.color: "red"

            Canvas {
                id: canvasId2
                x:17;y:2
                property color triangleColor: "#474747"
                width:8; height: 12
                contextType: "2d"
                onPaint: {
                    context.lineWidth = 0
                    context.strokeStyle = "#00000000"
                    context.fillStyle = triangleColor
                    context.beginPath();
                    context.moveTo(0, 0)
                    context.lineTo(0, canvasId2.height);
                    context.lineTo(canvasId2.width, canvasId2.height/2);
                    context.closePath();
                    context.fill()
                    context.stroke();
                }
            }
        }

        //第一個(gè)輸出口
        Rectangle {
            x: 86;y:40
            width: 16    //width
            height: 16   //=width
            //color: Qt.rgba(200/255,0/255,0/255, 0.5)
            color: "black"
            radius: 8   //width/2
            border.color: "red"

            Canvas {
                id: canvasId3
                x:17;y:2
                property color triangleColor: "#474747"
                width:8; height: 12
                contextType: "2d"
                onPaint: {
                    context.lineWidth = 0
                    context.strokeStyle = "#00000000"
                    context.fillStyle = triangleColor
                    context.beginPath();
                    context.moveTo(0, 0)
                    context.lineTo(0, canvasId3.height);
                    context.lineTo(canvasId3.width, canvasId3.height/2);
                    context.closePath();
                    context.fill()
                    context.stroke();
                }
            }
        }//第一個(gè)輸出口
        //txt操作框
        Rectangle {
            id:optxt
            x:40;y:60
            width: 40
            height: 15
            color: "black"
            border.color: "grey"
            anchors.horizontalCenter: myobj.Center
            TextInput {
                text:"+"
                id: opInput
                color:"red"
                anchors.fill: parent
                anchors.margins: 2
                font.pointSize: 8
                //focus: true
                anchors.horizontalCenter: optxt.Center
            }

            MouseArea {
                anchors.fill: parent
                acceptedButtons: Qt.LeftButton | Qt.RightButton
                onClicked: {            //右鍵
                    if(mouse.button === Qt.RightButton)
                    {
                        //optxt.color =  "blue"
                        opInput.text = "-"
                    }
                    //左鍵 + shift鍵
                    else if((mouse.button === Qt.LeftButton) && (mouse.modifiers & Qt.ShiftModifier))
                    {
                        //optxt.color = "green"
                        opInput.text = "*"
                    }
                    else
                    {
                        //optxt.color = "yello"
                        opInput.text = "/"
                    }

                }
            }


        }

        MouseArea {
            propagateComposedEvents: true //組合事件,可以傳遞到下一層的鼠標(biāo)事件
            anchors.fill: parent
            //! [drag]
            drag.target: myobj
            drag.axis: Drag.XAndYAxis
            //drag.minimumX: 0
            //drag.maximumX: parent.width
            //drag.minimumY: 0
            //drag.maximumY: parent.height
            //! [drag]
            onClicked: {
                console.log("item clicked")
                //組合事件可以不寫處理程序,或者accepted為false
                mouse.accepted = false
            }
        }
    }//背景框
}

五,總結(jié)

從一開(kāi)沒(méi)有方向,到后來(lái)有了很多方向,但是暫時(shí)還是有實(shí)現(xiàn)完整的功能,只實(shí)現(xiàn)了炫酷界面部分功能,這也是一種探索學(xué)習(xí)后的進(jìn)步,算是一個(gè)關(guān)鍵的里程碑,所以特此記錄。而我本輪的主要目的不是想到什么好玩的工具,然后進(jìn)行實(shí)現(xiàn),其實(shí)主要目的就是學(xué)習(xí)定義HMI炫酷界面,因?yàn)槲抑白约航o自己做的工具感覺(jué)界面美觀方面都太簡(jiǎn)單了。此次主要是掌握了方法,為將來(lái)自己做好玩的工具進(jìn)行準(zhǔn)備,現(xiàn)在已經(jīng)達(dá)成目標(biāo)了,可以close file了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容