3

使用fbs打包 PyQt5 应用程序,从非 GUI 代码访问资源文件的最干净的方法是什么?

在下面的示例中,我制作了一个简单的 PyQt5 应用程序,其中一个窗口包含一个按钮。该按钮触发一个函数,该函数将读取资源文件并在控制台中.json打印其属性。logic.py中定义message的函数也应该在没有 GUI 应用程序的情况下工作,例如由其他 python 脚本使用。因此,它不能作为 MainWindow 类的方法移动。print_data()

使用应用程序上下文的get_resource()方法来获取mainwindow.ui的路径既简单又方便。不幸的是,它不能用于print_data()获取static_data.json的路径,因为该函数无法访问应用程序上下文。

最好的解决方案是什么?

  • 仅将 fbs 的资源系统用于 gui 相关的资源文件并将static_data.json与 python 文件一起保存?
  • 尝试访问 MainWindow 类之外的应用程序上下文?
  • 使用pkg_resources等其他 python 资源库来处理非 gui 相关的资源文件?
  • 使用cx_freeze等其他工具打包应用程序?

目录结构:

|-- src
|  |-- main
|  |  |-- python
|  |  |  |-- main.py
|  |  |  |-- gui.py
|  |  |  |-- logic.py
|  |  |-- resources
|  |  |  |-- base
|  |  |  |  |-- mainwindow.ui
|  |  |  |  |-- static_data.json

内容main.py

from fbs_runtime.application_context.PyQt5 import ApplicationContext
import sys
from gui import MainWindow

if __name__ == '__main__':
    appctxt = ApplicationContext()
    window = MainWindow(appctxt)
    window.show()
    exit_code = appctxt.app.exec_()
    sys.exit(exit_code)

内容gui.py

from PyQt5.QtWidgets import QMainWindow
from PyQt5 import uic

from logic import print_data


class MainWindow(QMainWindow):
    def __init__(self, context):
        super().__init__()

        # Loading the .ui file from the resources
        self.ui = uic.loadUi(context.get_resource("mainwindow.ui"), self)

        # Binding the button to the print_data function defined in logic.py
        self.main_button.clicked.connect(print_data)

内容logic.py

import json


def print_data():

    # Getting the resource data filepath
    filepath = "../resources/base/static_data.json"

    # Processing the resource file
    with open(filepath) as file:
        data = json.load(file)
        print(data["message"])
4

1 回答 1

5
python
├── base.py
├── gui.py
├── logic.py
└── main.py

一种可能的解决方案是在每个人都可以访问该变量的文件中创建上下文:

基础.py

from fbs_runtime.application_context.PyQt5 import ApplicationContext

context = ApplicationContext()

然后在其他类中使用它:

gui.py

from PyQt5.QtWidgets import QMainWindow
from PyQt5 import uic

from base import context

from logic import print_data


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # Loading the .ui file from the resources
        self.ui = uic.loadUi(context.get_resource("mainwindow.ui"), self)

        # Binding the button to the print_data function defined in logic.py
        self.main_button.clicked.connect(print_data)

逻辑.py

import json

from base import context


def print_data():
    # Getting the resource data filepath
    filepath = context.get_resource("static_data.json")

    # Processing the resource file
    with open(filepath) as file:
        data = json.load(file)
        print(data["message"])

主文件

import sys

from base import context
from gui import MainWindow

if __name__ == "__main__":
    window = MainWindow()
    window.resize(250, 150)
    window.show()
    exit_code = context.app.exec_()
    sys.exit(exit_code)
于 2020-02-03T16:21:39.670 回答