在非GUI代码中访问fbs资源文件
Access fbs resource files in non-GUI code
使用 fbs 打包 PyQt5 应用程序,从非 GUI 代码访问资源文件的最干净的方法是什么?
在下面的示例中,我制作了一个简单的 PyQt5 应用程序,其中 window 包含一个按钮。该按钮触发一个函数,该函数将读取 .json
资源文件并在控制台中打印其属性 message
。 logic.py 中定义的函数 print_data()
也应该在没有 GUI 应用程序的情况下工作,例如被其他 python 脚本使用。因此,它不能作为 MainWindow 的方法移动 class.
使用应用程序上下文的 get_resource()
方法获取 mainwindow.ui 的路径既简单又方便。不幸的是,print_data()
无法使用它来获取 static_data.json 的路径,因为该函数无法访问应用程序上下文。
最好的解决方案是什么?
- 只对gui相关的资源文件使用fbs的资源系统,static_data.json与python文件一起保留?
- 尝试在 MainWindow 之外访问应用程序上下文 class?
- 使用另一个python资源库如pkg_resources来处理非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"])
python
├── base.py
├── gui.py
├── logic.py
└── main.py
一种可能的解决方案是在文件中创建上下文,每个人都可以在其中访问该变量:
base.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)
logic.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"])
main.py
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)
使用 fbs 打包 PyQt5 应用程序,从非 GUI 代码访问资源文件的最干净的方法是什么?
在下面的示例中,我制作了一个简单的 PyQt5 应用程序,其中 window 包含一个按钮。该按钮触发一个函数,该函数将读取 .json
资源文件并在控制台中打印其属性 message
。 logic.py 中定义的函数 print_data()
也应该在没有 GUI 应用程序的情况下工作,例如被其他 python 脚本使用。因此,它不能作为 MainWindow 的方法移动 class.
使用应用程序上下文的 get_resource()
方法获取 mainwindow.ui 的路径既简单又方便。不幸的是,print_data()
无法使用它来获取 static_data.json 的路径,因为该函数无法访问应用程序上下文。
最好的解决方案是什么?
- 只对gui相关的资源文件使用fbs的资源系统,static_data.json与python文件一起保留?
- 尝试在 MainWindow 之外访问应用程序上下文 class?
- 使用另一个python资源库如pkg_resources来处理非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"])
python
├── base.py
├── gui.py
├── logic.py
└── main.py
一种可能的解决方案是在文件中创建上下文,每个人都可以在其中访问该变量:
base.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)
logic.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"])
main.py
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)