我有一个在pycharm IDE中开发的大型应用程序。可以从IDE中调试和运行它。该应用程序也可以(通常(从终端命令行启动并以这种方式运行。
我需要这个应用程序是一个可执行程序,并且我可以使用pyinstaller成功地将这个python应用程序转换为在Ubuntu中运行的可执行程序。
我使用以下命令来执行此操作:
sudo pyinstaller App.py --onefile
当我运行可执行文件时,它会出现并按预期执行所有任务,只是它不会绘制某些图形(由应用程序计算的自定义圆弧和矩形(。
控制台打印以下错误:
"TypeError: Couldn't find foreign struct converter for 'cairo.Context'"
这些问题似乎与各种环境中的包有关。
从终端,我可以确认我已经安装了python3-gi和python3gi-cairo包。
例如:
$sudo apt install python3-gi
Reading package lists... Done
Building dependency tree
Reading state information... Done
python3-gi is already the newest version (3.36.0-1).
0 upgraded, 0 newly installed, 0 to remove and 34 not upgraded.
当我从命令行或IDE运行App.py时,图形会按预期渲染。
但是,在构建可执行文件时,图形会出现问题。
我尝试过在不使用--onefile的情况下构建可执行文件,但得到了相同的结果,因此它不涉及--onefile参数。
我相信有一些上下文是通过pycharm IDE设置的,它没有被pyinstaller导入或处理。我注意到,在源代码中,我们没有在任何地方使用cairo这个词,当它被导入时,IDE会将其灰显,因为它在任何地方都没有被引用
GTK表单是从Glade构建的XML文件中构建的,然后使用GTK_Builder(formfile.grade(拉入该XML文件。
下面是我移动到一个单独的draw.py应用程序中测试的一些图形的最小示例:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk as gtk
from math import pi
class App:
def __init__(self):
self.sw_ver = "0.1"
try:
self.builder = gtk.Builder()
self.builder.add_from_file("testDraw.glade")
self.plotRingGaugeArea = self.builder.get_object("testView")
self.plotRingGaugeArea.connect('draw', self.on_draw_ring_gauge)
except Exception as e:
print("Exception can_processing_thread: " + str(e))
def on_draw_ring_gauge(self, da, ctx):
radius = 275
gaugeWidth = 1180 / 4
line_width = radius / 6
start_angle = pi * 0.7
pegged = 0.8
try:
percent_spd = 50
spd_end_angle = start_angle + min(0.99, percent_spd) * (2 * pi) * pegged # max angle at 80% for speed
ctx.set_source_rgb(20, 20, 200)
ctx.set_line_width(line_width)
ctx.set_tolerance(0.1)
ctx.arc(gaugeWidth,
radius,
radius * 0.9,
start_angle,
spd_end_angle)
ctx.stroke()
ctx.set_source_rgb(1, 1, 1)
ctx.fill()
while(1):
a = 1000 #hang here...
except Exception as e:
print("Error - on_draw_ring_gauge part 1: " + str(e))
if __name__ == "__main__":
try:
app = App()
except Exception as e:
print(e)
但是,这个文件不能正常工作,因为它缺少程序包。我已经开始在pycharm中的新的最小项目中添加一些,然而,当我查看实际应用程序中安装的包的列表时,有100多个包(其中一些可能不会随着应用程序的开发而使用(。我现在正在添加包以启用最小draw.py项目。。。
这里有一个最小的glade文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.2 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="testWindow">
<property name="can_focus">False</property>
<child type="titlebar">
<placeholder/>
</child>
<child>
<object class="GtkFixed" id="testFixed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkViewport" id="testView">
<property name="name">myViewport</property>
<property name="width_request">500</property>
<property name="height_request">500</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
---
关键问题是:我需要做什么才能让pyinstaller包含从命令行运行应用程序所需的一切(在IDE之外,没有python源代码(。
问题是其中一个python文件中没有导入python模块。添加:
import cairo
解决了问题。我不确定为什么在没有导入的情况下,python上的一切都能正常工作,但有了它,pyinstaller可以正确地构建可执行文件。