【问题标题】:Pass a .ui file created with Qt designer to fbs for packaging将使用 Qt 设计器创建的 .ui 文件传递​​给 fbs 进行打包
【发布时间】:2020-03-31 09:34:51
【问题描述】:

我编写了一个 Python 应用程序,我想分发它。我已经在它之上构建了一个 GUI,并且到目前为止工作正常。我使用以下设置 GUI:

qtCreatorFile = "gui.ui" 
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)

class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        # Initialize parent PyQt classes
        QtWidgets.QMainWindow.__init__(self)
        self.setupUi(self)
        (....)

应用程序以以下内容开头:

if __name__ == "__main__":
     app = QtWidgets.QApplication(sys.argv)
     window = MyApp()
     window.show()
     sys.exit(app.exec_())  

如果我理解正确,对于使用 fbs 打包的“gui.ui”文件,我应该将其作为资源加载。所以我用这些作为修改:

from fbs_runtime.application_context import ApplicationContext, cached_property #added to imports)

class AppContext(ApplicationContext):           # Subclass ApplicationContext
    def run(self):
        qtCreatorFile=self.get_design()    # to get the .ui file
        Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
        window = MyApp()
        version = self.build_settings['version']
        window.setWindowTitle("EPANET parser v" + version)
        window.show()
        return self.app.exec_()

    def get_design(self):
        qtCreatorFile=self.get_resource("gui.ui") # It is in the correct src\main\resources path
        return qtCreatorFile

    @cached_property # all tutorials suggest this , but don't understand why. ???
    def main_window(self):
        return MainWindow(self)

fbs 应用程序应该以 if __name__ == '__main__:' 的以下替换开始:

if __name__ == '__main__':
    appctxt = AppContext()    
    exit_code = appctxt.app.exec_()
    sys.exit(exit_code)

但是,我收到以下错误: Traceback (most recent call last): File "C:\Users\....src\main\python\main.py", line 61, in <module> class MyApp(QtWidgets.QMainWindow, Ui_MainWindow): NameError: name 'Ui_MainWindow' is not defined

我知道 MyApp 继承自 Ui_MainWindow 现在在 AppContext 类中定义,MyApp 无法引用它。任何帮助将不胜感激!

【问题讨论】:

  • 我想您从第一个 sn-p 中显示的主缩进中删除了 loadUiType,对吧?
  • 是的,我删除了它!
  • 我应该提醒任何将来看到这个问题的人,我的错误之一是 .ui 文件应该位于 \src\main\resources\base 路径中。另一个错误已通过接受的答案解决。

标签: python pyqt5 python-packaging fbs


【解决方案1】:

您可以使用 uic.loadUi() 而不是使用 uic.loadUiType(),它只是通过传递 .ui 路径来填充窗口

ma​​in.py

from fbs_runtime.application_context.PyQt5 import ApplicationContext, cached_property

import sys

from mainwindow import MyApp


class AppContext(ApplicationContext):
    def run(self):
        self.window.resize(640, 480)
        self.window.show()
        return appctxt.app.exec_()

    def get_design(self):
        qtCreatorFile = self.get_resource("gui.ui")
        return qtCreatorFile

    @cached_property
    def window(self):
        return MyApp(self.get_design())


if __name__ == "__main__":
    appctxt = AppContext()
    exit_code = appctxt.run()
    sys.exit(exit_code)

ma​​inwindow.py

from PyQt5 import QtWidgets, uic


class MyApp(QtWidgets.QMainWindow):
    def __init__(self, ui, parent=None):
        super().__init__(parent)
        uic.loadUi(ui, self)
        # ...
└── src
    ├── build
    │   └── settings
    │       ├── base.json
    │       ├── linux.json
    │       └── mac.json
    └── main
        ├── icons
        │   ├── base
        │   │   ├── 16.png
        │   │   ├── 24.png
        │   │   ├── 32.png
        │   │   ├── 48.png
        │   │   └── 64.png
        │   ├── Icon.ico
        │   ├── linux
        │   │   ├── 1024.png
        │   │   ├── 128.png
        │   │   ├── 256.png
        │   │   └── 512.png
        │   ├── mac
        │   │   ├── 1024.png
        │   │   ├── 128.png
        │   │   ├── 256.png
        │   │   └── 512.png
        │   └── README.md
        ├── python
        │   ├── main.py
        │   └── mainwindow.py
        └── resources
            └── base
                └── gui.ui

【讨论】:

  • 谢谢!这解决了问题,所以我关闭了这个问题。运行命令 fbs run 可以正常工作,并且 GUI 会正常运行。但是,使用命令 fbs freeze 我没有遇到错误,但生成的 .exe 无法启动。它给出了“检测到致命错误:未能执行脚本 fbs_pyinstaller_hook。有任何想法吗?编辑:我的 venv 包含 Python 3.6.4、PyInstaller 3.4、PyQt 5.9.2、pywin32 和更新的 pandas numpy 和 networkx 库。第一次它没有工作我得到错误没有模块win32com,所以我安装了库pywin32。
  • 除了安装 fbs,您还应该手动安装 pyinstaller,例如在 anaconda 中:conda install -c conda-forge pyinstaller
  • PyInstaller 安装在我用于开发的虚拟环境中。我还尝试按照此线程中的建议手动安装pyinstaller-hooks,但它也不起作用。 stackoverflow.com/questions/58479154/…
  • 我终于通过在新的空虚拟环境(使用 Python 3.5.6)中手动安装正确版本所需的内容来解决问题。我不知道是不是 Python 版本的问题,但现在可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 2011-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多