Python-QML集成#
本教程提供了一步一步的快速浏览,展示了如何加载并交互一个QML文件的应用程序。QML是一种声明式语言,它允许您比C++等传统语言更快地设计UI。QtQml和QtQuick模块提供基于QML的UI所需的基础结构。
在本教程中,您将学习如何将Python与QML应用程序集成。这种机制将帮助您了解如何将Python作为后端,以响应QML界面中UI元素发出的某些信号。此外,您还将学习如何使用Qt Quick Controls 2中的一个特性为您的QML应用程序提供现代的外观。
本教程基于一个允许您设置许多文本属性的应用程序,例如增加字体大小、更改颜色、更改样式等。在开始之前,请安装PySide6
Python包。
以下逐步过程将引导您了解基于QML的应用程序和PySide6集成的关键元素。
首先,让我们从以下基于QML的UI开始
设计基于
GridLayout
,包含两个ColumnLayout
。在UI中,您将找到许多RadioButton
、Button
和一个Slider
。有了QML文件,您可以通过Python加载它
1 2if __name__ == '__main__': 3 app = QGuiApplication(sys.argv) 4 QQuickStyle.setStyle("Material") 5 engine = QQmlApplicationEngine() 6 7 # Get the path of the current directory, and then add the name 8 # of the QML file, to load it. 9 qml_file = Path(__file__).parent / 'view.qml' 10 engine.load(qml_file) 11 12 if not engine.rootObjects(): 13 sys.exit(-1) 14
注意,我们只需要一个
QQmlApplicationEngine
来加载QML文件。定义
Bridge
类,包含将要注册到QML的所有逻辑1# To be used on the @QmlElement decorator 2# (QML_IMPORT_MINOR_VERSION is optional) 3QML_IMPORT_NAME = "io.qt.textproperties" 4QML_IMPORT_MAJOR_VERSION = 1 5 6 7@QmlElement 8class Bridge(QObject): 9 10 @Slot(str, result=str) 11 def getColor(self, s): 12 if s.lower() == "red": 13 return "#ef9a9a" 14 elif s.lower() == "green": 15 return "#a5d6a7" 16 elif s.lower() == "blue": 17 return "#90caf9" 18 else: 19 return "white" 20 21 @Slot(float, result=int) 22 def getSize(self, s): 23 size = int(s * 34) 24 if size <= 0: 25 return 1 26 else: 27 return size 28 29 @Slot(str, result=bool) 30 def getItalic(self, s): 31 if s.lower() == "italic": 32 return True 33 else: 34 return False 35 36 @Slot(str, result=bool) 37 def getBold(self, s): 38 if s.lower() == "bold": 39 return True 40 else: 41 return False
注意,注册过程得益于
QmlElement
装饰器,它底层使用对Bridge
类的引用以及变量QML_IMPORT_NAME
和QML_IMPORT_MAJOR_VERSION
。现在,回到QML文件,并将信号连接到在
Bridge
类中定义的槽Bridge { id: bridge }
在
ApplicationWindow
内部,我们声明一个与Python类同名组件,并提供一个id:
。这个id
将帮助您获取从Python注册的元素的引用。1 RadioButton { 2 id: italic 3 Layout.alignment: Qt.AlignLeft 4 text: "Italic" 5 onToggled: { 6 leftlabel.font.italic = bridge.getItalic(italic.text) 7 leftlabel.font.bold = bridge.getBold(italic.text) 8 leftlabel.font.underline = bridge.getUnderline(italic.text) 9 10 } 11 }
属性Italic、Bold和Underline是互斥的,这意味着任何时候只能有一个处于激活状态。为了实现这一点,每次我们选择这些选项之一时,我们都通过如您在上文小段中看到的那样,通过QML元素属性检查这三个属性。其中只有一个将返回True,而其他两个将返回False,这就是我们确保只有一个应用于文本的方法。
每个槽都会验证选定的选项是否包含与属性关联的文本
1 @Slot(str, result=bool) 2 def getItalic(self, s): 3 if s.lower() == "italic": 4 return True 5 else: 6 return False
返回True或False允许您激活和关闭QML UI元素的属性。
还可以返回其他不是Boolean类型的值,例如负责返回字体大小的槽
1 @Slot(float, result=int) 2 def getSize(self, s): 3 size = int(s * 34) 4 if size <= 0: 5 return 1 6 else:
现在,要更改我们应用程序的外观,您有两个选项
使用命令行:执行python文件时添加选项,
--style
python main.py --style material
使用一个
qtquickcontrols2.conf
文件1[Controls] 2Style=Material 3 4[Universal] 5Theme=System 6Accent=Red 7 8[Material] 9Theme=Dark 10Accent=Red
然后将其添加到您的
.qrc
文件中1<!DOCTYPE RCC><RCC version="1.0"> 2<qresource prefix="/"> 3 <file>qtquickcontrols2.conf</file> 4</qresource> 5</RCC>
运行,
pyside6-rcc style.qrc -o style_rc.py
,生成rc文件。最后,从您的main.py
脚本中导入它。
1import sys 2from pathlib import Path 3 4from PySide6.QtCore import QObject, Slot 5from PySide6.QtGui import QGuiApplication 6from PySide6.QtQml import QQmlApplicationEngine, QmlElement 7from PySide6.QtQuickControls2 import QQuickStyle 8 9import style_rc
您可以在这里了解更多有关此配置文件的信息。
您应用程序的最终外观将是这样