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