扩展文件系统资源管理器示例

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

Extended Explorer GIF

定义颜色方案

要定义您的配色方案,您可以使用与原始示例相同的颜色名称,这样您就不必重命名每个出现的地方。原始颜色在Colors.qml文件中定义如下:

true
 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 方案。

true
 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类:

true
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成员函数。

true
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.作为可分配属性。

true
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中包含的键。

true
1    @Property(QColor, notify=schemeChanged)
2    def background(self):
3        return self.m_activeScheme["background"]

为了使颜色属性在QML中可分配,使用@Property装饰器。 我们只需从字典中返回每个属性对应的颜色值。这个过程会为应用程序中使用的所有其他颜色重复进行。 此时,应用程序应该从构造函数中提供的活动方案的颜色开始。

将方案切换添加到QML

要可视化当前方案并启用交互式方案切换,首先在Sidebar.qml文件中添加一个新条目。

true
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文件中进行:

true
 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文件。

true
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

true
 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中被分配为一个属性。这样做的原因是为了在颜色方案切换时接收通知,以便可以更新应用程序中显示的颜色。颜色方案的键仅在应用程序启动时加载一次,并且不依赖于任何通知。

Extended Explorer GIF