Доступ к файлам ресурсов fbs в не-GUI коде - PullRequest
1 голос
/ 03 февраля 2020

Используя fbs для упаковки приложения PyQt5, какой самый простой способ получить доступ к файлам ресурсов из кода, отличного от GUI?

В приведенном ниже примере я сделал простой Приложение PyQt5 с одним окном, содержащим одну кнопку. Кнопка запускает функцию, которая читает файл ресурса .json и печатает его атрибут message в консоли. Функция print_data(), определенная в logi c .py , также должна работать без приложения GUI, например, для использования другими сценариями python. Поэтому его нельзя перемещать как метод класса MainWindow.

Легко и удобно использовать метод get_resource() контекста приложения, чтобы получить путь к mainwindow.ui . К сожалению, print_data() не может использовать его для получения пути к static_data. json, так как функция не имеет доступа к контексту приложения.

Что было бы лучшим решением?

  • Использовать систему ресурсов fbs только для gui файлов ресурсов и сохранять static_data. json с файлами python?
  • Попробуйте получить доступ к контексту приложения вне класса MainWindow?
  • Использовать другую 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"])

1 Ответ

1 голос
/ 03 февраля 2020
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)

logi c .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)
...