扩展文件系统资源管理器示例¶
本教程展示了如何通过添加一个简单的方案管理器来扩展 文件系统浏览器示例 。此功能将允许您在应用程序运行时切换颜色方案。颜色方案将以JSON格式声明,并通过自定义的Python-QML插件提供。

定义颜色方案¶
要定义您的配色方案,您可以使用与原始示例相同的颜色名称,这样您就不必重命名每个出现的地方。原始颜色在Colors.qml文件中定义如下:
1QtObject {
2 readonly property color background: "#23272E"
3 readonly property color surface1: "#1E2227"
4 readonly property color surface2: "#090A0C"
5 readonly property color text: "#ABB2BF"
6 readonly property color textFile: "#C5CAD3"
7 readonly property color disabledText: "#454D5F"
8 readonly property color selection: "#2C313A"
9 readonly property color active: "#23272E"
10 readonly property color inactive: "#3E4452"
11 readonly property color folder: "#3D4451"
12 readonly property color icon: "#3D4451"
13 readonly property color iconIndicator: "#E5C07B"
14 readonly property color color1: "#E06B74"
15 readonly property color color2: "#62AEEF"
16}
schemes.json 文件保存了配色方案。要开始实现这一点,你可以使用 Catppuccin 方案。
1 "Catppuccin": {
2 "background": "#1E1E2E",
3 "surface1": "#181825",
4 "surface2": "#11111B",
5 "text": "#CDD6F4",
6 "textFile": "#CDD6F4",
7 "disabledText": "#363659",
8 "selection": "#45475A",
9 "active": "#1E1E2E",
10 "inactive": "#6C7086",
11 "folder": "#6C7086",
12 "icon": "#6C7086",
13 "iconIndicator": "#FFCC66",
14 "color1": "#CBA6F7",
15 "color2": "#89DCEB"
16 },
除了“Catppuccin”配色方案外,还实现了其他四种配色方案:Nordic、One Dark、Gruvbox和Solarized。不过,请随意发挥创意,尝试你的方案。
要定义一个新的配色方案,请从上方复制结构并提供您的颜色值
实现方案管理器¶
在定义了配色方案之后,您可以实现实际的方案管理器。
管理器将读取schemes.json文件,并提供QML绑定以在运行时切换方案。
要实现方案管理器,创建一个Python-QML插件,将SchemeManager对象暴露给QML。该对象将具有从schemes.json文件加载颜色方案并在它们之间切换的方法。
在你的项目目录中创建一个名为schememanager.py的新Python文件。在这个文件中,定义SchemeManager类:
1QML_IMPORT_NAME = "FileSystemModule"
2QML_IMPORT_MAJOR_VERSION = 1
3
4
5@QmlNamedElement("Colors")
6@QmlSingleton
7class SchemeManager(QObject):
为了顺利集成到现有代码中,将SchemeManager附加到已经存在的QML模块中,使用QML_IMPORT_NAME = "FileSystemModule"。此外,使用@QmlNamedElement装饰器来顺利过渡到使用自定义插件,而不是Colors.qml文件。通过这些更改,我们可以避免编辑所有以前的赋值,例如:
import FileSystemModule
...
Rectangle {
color: Colors.background
}
构造函数在应用程序启动时读取schemes.json文件一次,然后调用setTheme成员函数。
1
2 schemeChanged = Signal()
3
4 def __init__(self, parent=None):
5 super().__init__(parent=parent)
6 with open(Path(__file__).parent / "schemes.json", 'r') as f:
7 self.m_schemes = json.load(f)
通过将SchemeManager作为名为Colors的可调用QML元素添加到FileSystemModule中,该类现在可以在代码中访问,而无需每次导入或编辑先前的分配。这反过来将简化工作流程。
在JSON格式中定义方案并将SchemeManager类作为QML中名为Colors的可调用元素后,还有两个步骤需要完成,以完全将新的方案管理器集成到示例中。
第一步是在SchemeManager类中创建一个函数,该函数从JSON文件加载颜色方案。第二步是使各个颜色在QML中以相同的名称可用,使用语法Colors.作为可分配属性。
1 self.m_activeSchemeName = "Catppuccin"
2 self.setScheme(self.m_activeSchemeName)
3
4 @Slot(str)
5 def setScheme(self, theme):
6 for k, v in self.m_schemes[theme].items():
setScheme 方法负责在颜色方案之间切换。为了使此方法在 QML 中可访问,请使用 @Slot(str) 装饰器并指定它接受一个字符串作为输入参数。在此方法中,我们用 JSON 文件中的颜色值填充字典。
注意:为了简化原因,没有执行其他错误检查。 您可能希望验证json中包含的键。
1 @Property(QColor, notify=schemeChanged)
2 def background(self):
3 return self.m_activeScheme["background"]
为了使颜色属性在QML中可分配,使用@Property装饰器。
我们只需从字典中返回每个属性对应的颜色值。这个过程会为应用程序中使用的所有其他颜色重复进行。
此时,应用程序应该从构造函数中提供的活动方案的颜色开始。
将方案切换添加到QML¶
要可视化当前方案并启用交互式方案切换,首先在Sidebar.qml文件中添加一个新条目。
1 // Shows the scheme switcher
2 SidebarEntry {
3 icon.source: "../icons/leaf.svg"
4 checkable: true
5
6 Layout.alignment: Qt.AlignHCenter
7 }
要更新应用程序的主要内容区域以显示ColorScheme,需要修改检查侧边栏按钮活动索引的逻辑。必要的更改将在Main.qml文件中进行:
1 // The main view that contains the editor or the scheme-manager.
2 StackLayout {
3 currentIndex: sidebar.currentTabIndex > 1 ? 1 : 0
4
5 SplitView.fillWidth: true
6 SplitView.fillHeight: true
7
8 Editor {
9 id: editor
10 showLineNumbers: root.showLineNumbers
11 currentFilePath: root.currentFilePath
12 }
13
14 ColorScheme {
15 Layout.fillWidth: true
16 Layout.fillHeight: true
17 }
此外,更改应用程序的行为,使其包含两个StackLayouts:一个用于可调整大小的导航,另一个用于显示我们颜色方案切换功能的主要内容区域。这些更改也将应用于Main.qml文件。
1 // selected buttons inside the sidebar.
2 StackLayout {
3 anchors.fill: parent
4 currentIndex: sidebar.currentTabIndex > 1 ? 1 : sidebar.currentTabIndex
为了完成我们的实现,需要创建ColorScheme.qml文件。
实现过程很简单,遵循与原始示例相同的原则。如果有任何不清楚的地方,请参考提供的文档。
要显示所有颜色和方案名称,请使用Repeater。
Repeater的模型由我们的scheme_manager.py文件提供,作为一个QStringList。
1 // Display all used colors inside a row
2 Row {
3 anchors.centerIn: parent
4 spacing: 10
5
6 Repeater {
7 model: Colors.currentColors
8 Rectangle {
9 width: 35
10 height: width
11 radius: width / 2
12 color: modelData
13 }
14 }
15 }
在更详细地检查代码时,您会注意到有不同的方法来检索模型。getKeys()方法被定义为一个Slot,因此在调用时需要括号。另一方面,currentColors模型被定义为一个property,因此在QML中被分配为一个属性。这样做的原因是为了在颜色方案切换时接收通知,以便可以更新应用程序中显示的颜色。颜色方案的键仅在应用程序启动时加载一次,并且不依赖于任何通知。
