【问题标题】:Pyinstaller and pygubu's calendar frame cause a problempyinstaller 和 pygubu 的日历框架导致问题
【发布时间】:2022-01-25 08:40:00
【问题描述】:

我做了一个 pygubu python 应用程序,并决定冻结它,在解决了一些简单的问题后,我遇到了无法修复的问题:

Traceback (most recent call last):
  File "main.py", line 138, in <module>
  File "pygubu\__init__.py", line 30, in __init__
  File "main.py", line 38, in _create_ui
  File "pygubu\builder\__init__.py", line 166, in get_object
  File "pygubu\builder\__init__.py", line 215, in _realize
  File "pygubu\builder\__init__.py", line 215, in _realize
  File "pygubu\builder\__init__.py", line 225, in _realize
Exception: Class "pygubu.builder.widgets.calendarframe" not mapped
[13108] Failed to execute script 'main' due to unhandled exception!

我什至导入了一堆 pyugubu 模块来尝试解决这个问题,但它仍然不起作用:

from pygubu import builder
from pygubu.builder import ttkstdwidgets
from pygubu.builder import widgets
from pygubu.widgets import calendarframe
from pygubu import widgets

这可能无关紧要,但我用 auto-py-to-exe 冻结了它。我试过让它同时成为控制台应用程序、文件夹应用程序,但还是不行。

提前谢谢你。

【问题讨论】:

  • from pygubu.widgets.calendarframe import CalendarFrame 停留在 pygubu/builder/widgets/calendarframe.py 源和目标的开头不同。只需在代码中使用Tkinter(非常简单),了解模块可以更轻松地编写模块。底部答案无效。最好的问候,有美好的一天。
  • @dsgdfg Pygubu 让为 python 创建图形界面变得更加容易和快捷,我正在寻找一种方法来使用它提供的一个小部件,而不是有人告诉我去编写自己的 tkinter代码。 matle 的回答完美无缺。谢谢。
  • 我认为你是绝对正确的(对于初学者),但如果你不知道元素属性,键入相关性和条件函数真的会挑战你。如果你真的是用 Tkinter 写一个应用程序,它肯定不会使用 StringVar、IntVar 和许多定义,并且会切换得更快。
  • 我已经用 Tkinter 做了应用程序,我只是更喜欢 pygubu 提供的易用性

标签: python python-3.x pyinstaller pygubu


【解决方案1】:

1。创建测试项目

创建test.py(改编自here)(我包含了您提到的所有依赖项并列出了它们的属性和方法以确保包含模块):

import tkinter as tk
import pygubu
from pygubu import builder
from pygubu.builder import ttkstdwidgets
from pygubu.builder import widgets
from pygubu.widgets import calendarframe
from pygubu import widgets

class HelloWorldApp:
    
    def __init__(self):

        #1: Create a builder
        self.builder = builder = pygubu.Builder()

        #2: Load an ui file
        builder.add_from_file('test.ui')

        #3: Create the mainwindow
        self.mainwindow = builder.get_object('mainwindow')
        
    def run(self):
        self.mainwindow.mainloop()


if __name__ == '__main__':
    # just some calls to make sure the imports are loaded
    print(dir(pygubu))
    print(dir(builder))
    print(dir(ttkstdwidgets))
    print(dir(widgets))
    print(dir(calendarframe))
    print(dir(widgets))
    
    app = HelloWorldApp()
    app.run()

创建test.ui

<?xml version='1.0' encoding='utf-8'?>
<interface>
  <object class="tk.Toplevel" id="mainwindow">
    <property name="height">200</property>
    <property name="resizable">both</property>
    <property name="title" translatable="yes">Hello World App</property>
    <property name="width">200</property>
    <child>
      <object class="ttk.Frame" id="mainframe">
        <property name="height">200</property>
        <property name="padding">20</property>
        <property name="width">200</property>
        <layout>
          <property name="column">0</property>
          <property name="propagate">True</property>
          <property name="row">0</property>
          <property name="sticky">nsew</property>
          <rows>
            <row id="0">
              <property name="weight">1</property>
            </row>
          </rows>
          <columns>
            <column id="0">
              <property name="weight">1</property>
            </column>
          </columns>
        </layout>
        <child>
          <object class="ttk.Label" id="label1">
            <property name="anchor">center</property>
            <property name="font">Helvetica 26</property>
            <property name="foreground">#0000b8</property>
            <property name="text" translatable="yes">Hello World !</property>
            <layout>
              <property name="column">0</property>
              <property name="propagate">True</property>
              <property name="row">0</property>
            </layout>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>

2。安装 pyinstaller 和 pygubu

pip install pyinstaller pygubu

3。将pygubu模块复制到本地项目

  1. 导航到当前解释器的站点包文件夹(在 shell 中执行: python -c "import site; print(site.getsitepackages()[-1])",导航到返回的路径)
  2. 将整个 pygubu 文件夹复制到使用 test.py 脚​​本的位置

包含test.py的文件夹中的单行:

python -c "import shutil, site, os; shutil.copytree(site.getsitepackages()[-1]+os.sep+'pygubu', os.getcwd()+os.sep+'pygubu')"

4。运行pyinstaller,测试包

下面的语句直接添加了.ui文件以及整个pygubu包。然后,从dist/test 文件夹中运行test.exe

pyinstaller --clean --add-data=test.ui;. --add-data pygubu;pygubu test.py

我尝试使用 --onefile 运行 pyinstaller,但没有成功,--hidden-import--collect-data--collect-submodules--collect-all 也失败了。然而,这是一个非常丑陋的解决方案。


编辑

在发现了一个很棒的模块 auto-py-to-exe 是什么之后(感谢您提及它),我发现您可以将 --collect-all--onefile 结合使用,而无需复制 pygubu 库用手。但是,我无法设法包含 .ui 文件,因此我不得不手动复制:

pyinstaller --noconfirm --onefile --windowed --collect-all "pygubu"  "test.py" && python -c "import shutil, os; shutil.copyfile('test.ui', 'dist'+os.sep+'test.ui')"

【讨论】:

  • auto-py-to-exe 中有一个关于Additional Files 的部分,如果你向下滚动一点,它可以让你包含文件。您的解决方案奏效了,非常感谢。
  • @ParasolKirby 很高兴它成功了 :)
猜你喜欢
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 2017-04-07
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多