让Pyinstaller识别Kivy Garden Matplotlib模块的路径

时间:2016-12-19 17:53:21

标签: python matplotlib kivy pyinstaller

这类似于:Kivy Garden in PyInstaller - stuck trying to trace import,除了我将提供更多细节,希望能让人们更容易测试并提供具体的解决方案....

我使用Kivy 1.9.1构建了一个Python 2.7.13应用程序,并尝试使用Pyinstaller在Windows 10中为Windows打包它。简而言之 - 我无法让Pyinstaller获取Garden模块 - 特别是matplotlib模块,我用它来显示数据。这个花园模块是通过以下方式安装的:

garden.bat install matplotlib

我的应用程序太大而且很复杂,不能在这里发布,所以我发现了一个在线示例,其中包括尝试导入和使用模块的方式与我正在执行的方式基本相同。这是Python文件,从Python解释器运行时工作正常:

import matplotlib
matplotlib.use('module://kivy.garden.matplotlib.backend_kivy')
from matplotlib.figure import Figure
from numpy import arange, sin, pi
from kivy.app import App

import numpy as np
from matplotlib.mlab import griddata
from kivy.garden.matplotlib.backend_kivy import FigureCanvas,\
                                            NavigationToolbar2Kivy

from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from matplotlib.transforms import Bbox
from kivy.uix.button import Button
from kivy.graphics import Color, Line, Rectangle

import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

fig, ax = plt.subplots()

X = np.arange(-508, 510, 203.2)
Y = np.arange(-508, 510, 203.2)
X, Y = np.meshgrid(X, Y)

Z = np.random.rand(6, 6)

plt.contourf(X, Y, Z, 100, zdir='z', offset=1.0, cmap=cm.hot)
plt.colorbar()

ax.set_ylabel('Y [mm]')
ax.set_title('NAILS surface')
ax.set_xlabel('X [mm]')

canvas = fig.canvas



def callback(instance):

    global fig, ax

    X = np.arange(-508, 510, 203.2)
    Y = np.arange(-508, 510, 203.2)
    X, Y = np.meshgrid(X, Y)

    Z = 1000*np.random.rand(6, 6)
    plt.clf()
    plt.contourf(X, Y, Z, 100, zdir='z', offset=1.0, cmap=cm.hot)
    plt.colorbar()

    canvas.draw()


class MatplotlibTest(App):
    title = 'Matplotlib Test'

    def build(self):
        fl = BoxLayout(orientation="vertical")
        a = Button(text="press me", height=40, size_hint_y=None)
        a.bind(on_press=callback)

        fl.add_widget(canvas)
        fl.add_widget(a)
        return fl

if __name__ == '__main__':
    MatplotlibTest().run()

Pyinstaller以及Python解释器都放在我的Windows路径上,所以当我通过Windows Powershell将上述文件(名为mplTest.py)传递给Python解释器时

python mplTest.py

一切都像魅力一样。但是,尝试使用以下命令打包它:

pyinstaller mplTest.py

按预期产生./dist/和./build/目录,以及pyinstaller规范文件。如果我导航到./dist/mplTest/目录并尝试运行文件mplTest.exe(pyinstaller生成的可执行文件),我会将以下内容作为日志消息的一部分:

[WARNING           ] stderr: Traceback (most recent call last):
[WARNING           ] stderr:   File "mplTest.py", line 10, in <module>
[WARNING           ] stderr: ImportError: No module named garden.matplotlib.backend_kivy

我试图用:

修改.spec文件中的hidden_​​imports
hiddenimports=['garden.matplotlib.backend_kivy'],

但是当尝试使用pyinstaller编译.spec文件时,我最终得到了这一行:

362 ERROR: Hidden import 'garden.matplotlib.backend_kivy' not found

有人可以在这里提出建议吗?提到的链接SO线程中的一个用户使用:

garden.bat install --app matplotlib

创建安装了这些目录的./libs/garden/目录,也许有人可以告诉我如何从spec文件中链接到这些目录?

我真的打败了这个人,而且投入这么多的开发时间而被困在可能非常微不足道的事情上是很痛苦的......如果有必要,我很乐意提供更多信息。 / p>

提前致谢。

3 个答案:

答案 0 :(得分:1)

我通过重新安装 garden.matplotlib

解决了这个问题

您需要使用:

CollectionAssert

当您安装 garden.matplotlib 而没有 - kivy 标记时,它会安装在〜/ .kivy / garden / matplotlib 中夹。 Pyinstaller无法在那里找到它。设置 - kivy 标记时,会全局安装。 Pyinstaller可以在那里捕获它并自动包含它。

答案 1 :(得分:0)

您应该将'~/kivy/garden/matplotlib'添加到pathhex文件中的.spec

并更改hiddenimports=['backend_kivy']

答案 2 :(得分:0)

似乎对安装最有用的解决方案没有解决我的问题,但我找到了如何为我的项目修复它。

由于 matplotlib 版本与 Kivy 和 Garden 非常配合,因此版本 2.2.5 不再更新。我稍微改变了如何导入 Kivy 后端。

  1. 我将文件夹 name_of_your_venv/Lib/site-packages/matplotlib/backends 中的两个文件 backend_kivy.pybackend_kivyagg.py 添加到我的虚拟环境中。 >

  2. 在 matplotlib 库 (name_of_your_venv/Lib/site-packages/matplotlib) 的文件 rcsetup.py 中,我更改了交互式后端的名称列表,添加了 'Kivy' 和 {{1} } (l. 43 文件)

    'KivyAgg'
  3. 最后一步是更改项目中的导入

    interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'GTK3Agg', 'GTK3Cairo',
                      'MacOSX',
                      'nbAgg',
                      'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo',
                      'TkAgg', 'TkCairo',
                      'WebAgg',
                      'WX', 'WXAgg', 'WXCairo',
                      'Kivy', 'KivyAgg']
    

当您使用 PyInstaller 时,它将直接从您的 venv 的 matplotlib 库中获取文件,而不再从隐藏的导入中获取。

这个解决方案对我有用。我希望它也能帮助你。