PyQt импортирует тему QML из другого каталога - PullRequest
0 голосов
/ 23 февраля 2019

Я работаю над проектом 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 голосов
/ 23 февраля 2019

Простой вариант - использовать qresource, но перед этим вашей папке Темы необходимо создать qmldir:

qmldir

singleton Theme 1.0 Theme.qml

Итак, в концеВаш проект будет иметь следующую структуру:

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

Теперь создайте .qrc, который будет иметь .qml, и поместите его на стороне .py:

qml.qrc

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

Теперь вы должны преобразовать .qrc в .py, используя pyrcc5:

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_())

Вы можете найти полный проект здесь


ОБНОВЛЕНИЕ:

Также вы можете игнорировать .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_())

Вы можетенайти полный проект здесь

...