PyQt从不同目录导入QML主题

时间:2019-02-22 23:00:48

标签: python pyqt qml pyqt5

我正在研究PyQt项目。我想将主题放置在与主qml不同的文件夹中,并允许潜在地加载不同的主题。我的目录设置如下图所示。如何引用主题中的属性?我计划最终使它成为一个很大的项目,因此希望有一个良好的目录结构以使事情井井有条。 目前,我没有任何例外,但是背景颜色与我的Theme.qml文件中的颜色不匹配。

Directory structure

main.qml

import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12
import './Themes/'

ApplicationWindow
{
    id: mainWindow
    width: 640
    height: 480
    visible: true
    color:  Theme.primaryBackgroundColor
    title: qsTr("SmartDraw")
    flags: Qt.FramelessWindowHint | Qt.Window

    header: Rectangle {
        id: windowHeader
        height: 38
        width: parent.width
        color: "#0e6afa"

        MouseArea {
            id: windowResizeUp
            height: 2
            anchors.bottom: windowDragArea.top
            anchors.left: parent.left
            anchors.right: minimize.left
            cursorShape: Qt.SizeVerCursor
            property real lastMousePosY: 0

            onPressed: {
                lastMousePosY = mouse.y
            }
            onMouseYChanged:
            {
                var dy = (mouseY - lastMousePosY)
                mainWindow.y += dy
                mainWindow.height -= dy
            }
        }

        MouseArea {
            id: windowDragArea
            height: parent.height - 2
            anchors.bottom: parent.bottom
            anchors.left: parent.left
            anchors.right: minimize.left

            property point lastMousePos: Qt.point(0, 0)
            onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
            onMouseXChanged: mainWindow.x += (mouseX - lastMousePos.x)
            onMouseYChanged: mainWindow.y += (mouseY - lastMousePos.y)
        }

        Button {
            id: minimize
            width: 30
            height: parent.height
            anchors.right: maximize.left
            onClicked: mainWindow.showMinimized()

            background: Rectangle {
                width: parent.width
                height: parent.height
                color: windowHeader.color
            }

            Rectangle {
                color: "white"
                height: 2
                width: Math.round(parent.width*(2.0/3.0))
                anchors.centerIn: parent
            }
        }

        Button {
            id: maximize
            width: 30
            height: parent.height
            anchors.right: close.left
            onClicked: mainWindow.visibility == Window.Maximized ? mainWindow.showNormal() : mainWindow.showMaximized()

            background: Rectangle {
                width: parent.width
                height: parent.height
                color: windowHeader.color
            }

            Rectangle {
                color: "white"
                width: 15
                height: 15
            }
        }

        Button {
            id: close
            width: 30
            anchors.right: parent.right
            height: parent.height
            onClicked: Qt.quit()

            background: Rectangle {
                width: parent.width
                height: parent.height
                color: windowHeader.color
            }

            Text {
               color: "white"
               text: "X"
            }
        }
    }


    footer: Rectangle {
        id: windowFooter
        color: "#0e6afa"
        height: 23

        MouseArea {
            id: windowResizeBottomLeft
            width:  4
            height: 4
            anchors.left: parent.left
            anchors.bottom: parent.bottom
            cursorShape: Qt.SizeBDiagCursor

            property point lastMousePos: Qt.point(0,0)

            onPressed: {
                lastMousePos = Qt.point(mouse.x,mouse.y)
            }

            onMouseYChanged:
            {
                var dx = (mouseX - lastMousePos.x)
                var dy = (mouseY - lastMousePos.y)

                mainWindow.x += dx
                mainWindow.width -= dx
                mainWindow.height += dy
            }
        }

        MouseArea {
            id: windowResizeDown
            x: 4
            height: 2
            anchors.bottom: parent.bottom
            anchors.left: windowResizeBottomLeft.right
            anchors.right: parent.right
            cursorShape: Qt.SizeVerCursor

            property real lastMousePosY: 0

            onPressed: {
                lastMousePosY = mouse.y
            }

            onMouseYChanged:
            {
                var dy = (mouseY - lastMousePosY)
                mainWindow.height += dy
            }
        }
    }
}

Theme.qml

pragma Singleton
import QtQuick 2.8

QtObject {
    //Text Properties
    readonly property fontSize: 
    readonly property color primaryTextColor: "#D0D0D0"
    readonly property color disabledTextColor: "#909090"

    //F
    readonly property color focusedIconColor: "#D0D0D0"
    readonly property color diabledIconColor: 

    readonly property color primaryBackgroundColor: "#2A2A2A"
    readonly property color secondaryBackgroundColor: "#363636"

    //All Button Properties
    readonly property color disabledButtonColor: "#777777"

    //Primary Button Properties
    readonly property real primaryButtonBorderWidth: 2
    readonly property real primaryButtonBorderRadius: 5
    readonly property color primaryButtonBorderColor: "#D0D0D0"

    readonly property color primaryButtonColor: "#007acc"
    readonly property color primaryButtonHoverColor: "#018deb"
    readonly property color primaryButtonPressedColor: "#0165a8"

    //Toolbar Button Properties
}

加载QML文件

#Setup the application window & configure for high Dpi
os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" 
app = QGuiApplication(sys.argv)
app.setAttribute(Qt.AA_EnableHighDpiScaling)

#Initialize the QML rendering engine
engine = QQmlApplicationEngine()

#Load the main window element
ctx = engine.rootContext()
qml_file = os.path.join(dirname,'qml','main.qml')
engine.load(QUrl.fromLocalFile(os.path.abspath(qml_file)))
#Show the Application Window
win = engine.rootObjects()[0]
win.show()

#Execute and cleanup
app.exec_()

1 个答案:

答案 0 :(得分:1)

一个简单的选择是使用qresource,但是在此之前,您的文件夹Themes需要创建一个qmldir:

qmldir

singleton Theme 1.0 Theme.qml

最后,您的项目将具有以下结构:

|-- main.py
`-- qml
    |-- Themes
    |   |-- Theme.qml
    |   `-- qmldir
    `-- main.qml

现在创建一个将具有.qml的.qrc并将其放在.py的一侧:

qml.qrc

<RCC>
    <qresource prefix="/">
        <file>qml/main.qml</file>
        <file>qml/Themes/Theme.qml</file>
        <file>qml/Themes/qmldir</file>
    </qresource>
</RCC>

现在,您必须使用pyrcc5将.qrc转换为.py:

pyrcc5 qml.qrc -o qml_rc.py

具有以下结构:

|-- main.py
|-- qml
|   |-- Themes
|   |   |-- Theme.qml
|   |   `-- qmldir
|   `-- main.qml
|-- qml.qrc
`-- qml_rc.py

然后,您必须将qml_rc.py导入main.py并修改QUrl

import os
import sys
from PyQt5 import QtCore, QtGui, QtQml

import qml_rc

if __name__ == '__main__':
    os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" 
    app = QtGui.QGuiApplication(sys.argv)
    app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    #Initialize the QML rendering engine
    engine = QtQml.QQmlApplicationEngine()
    #Load the main window element
    ctx = engine.rootContext()
    engine.load(QtCore.QUrl("qrc:/qml/main.qml"))
    #Show the Application Window
    if not engine.rootObjects():
        sys.exit(-1)
    #Execute and cleanup
    sys.exit(app.exec_())

您可以找到完整的项目here


更新:

您也可以忽略.qrc:

|-- main.py
`-- qml
    |-- Themes
    |   |-- Theme.qml
    |   `-- qmldir
    `-- main.qml

具有以下main.py:

import os
import sys
from PyQt5 import QtCore, QtGui, QtQml

if __name__ == '__main__':
    os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" 
    app = QtGui.QGuiApplication(sys.argv)
    app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
    #Initialize the QML rendering engine
    engine = QtQml.QQmlApplicationEngine()
    #Load the main window element
    ctx = engine.rootContext()
    dirname = os.path.dirname(os.path.abspath(__file__))
    qml_file = os.path.join(dirname, 'qml','main.qml')
    engine.load(QtCore.QUrl.fromLocalFile(qml_file))
    #Show the Application Window
    if not engine.rootObjects():
        sys.exit(-1)
    #Execute and cleanup
    sys.exit(app.exec_())

您可以找到完整的项目here