質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.87%

  • Python

    6297questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    4794questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Tkinter

    106questions

    Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

  • Anaconda

    49questions

Python3.6.5とTkinterで作成したソースをpy2appでアプリ化したい

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 93

nyanten

score 0

 前提・実現したいこと

環境
macOS High Sierra 10.13
Python3.6.5 (おそらくhomebrewでインストールしました) 
Tkinterを使ってGUIアプリを作成しています。(ソースコードに関連するパッケージはpipでインストールしました)

py2appで.appへとビルドしたいのですが、いまいちうまくいきません。

 発生している問題・エラーメッセージ

ビルドできたが、.appを実行すると出てくるエラー

hoge has encountered a fatal error, and will now terminate

A Python runtime not could be located.
you may need to install a framework build of Python, or edit the 
PyRuntimeLocations array in this application's info.plist file


そもそもビルドできない時

Traceback (most recent call last):
  File "setup.py", line 5, in <module>
    setup_requires=['py2app'],
 File "/anaconda3/lib/python3.6/site-packages/setuptools/__init__.py", line 129, in setup
    return distutils.core.setup(**attrs)
 ...
 RecursionError: maximum recursion depth exceeded

 該当のソースコード

Tkinterを使ってGUIアプリを作ること自体が初めてでして...
様々なソースを参考にしながら作っています。

# -*- coding: utf-8 -*-
# build of python3.6 by OS X

# パッケージのインポート
# OpenCV使用
# 他のパッケージはpipコマンドでインストール
import sys, os
import cv2
import numpy
import tkinter as tk
import tkinter.filedialog as tkFD
from PIL import ImageTk, Image
from tkinter import PhotoImage

#RuntimeError: maximum recursion depth exceeded (再帰の数が深すぎるエラー)
#https://qiita.com/narupo/items/e25ac05a9065c0bd9c03
#http://sucrose.hatenablog.com/entry/2013/01/19/164008
sys.setrecursionlimit(50000) #再帰の最大数を増やす
LIMITER = sys.getrecursionlimit()
print("maximum recursion depth set: " + LIMITER)

class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack(expand=1, fill=tk.BOTH, anchor=tk.NW)
        # 基本ウィンドウ
        self.create_widgets()

    def create_widgets(self):
        # 各ウィジェット
        # 文字定義
        self.title = tk.Label(self, text=u"beta", font=("", 20))
        self.label = tk.Label(self, text=u"入力ファイル")

        # エントリ定義
        self.var_entry = tk.StringVar()
        self.entry = tk.Entry(self, textvariable=self.var_entry, width=22)

        # ボタン定義
        self.button = tk.Button(self, text=u"開く", command=self.button_pushed)
        self.button_qt = tk.Button(self, text=u"Quit", command=self.button_quit, width=5, height=2)
        self.button_act = tk.Button(self, text=u"命令セットを開く", command=self.button_action, width=15, height=2)

        #self.var_check = tk.BooleanVar()
        #self.check = tk.Checkbutton(self, text=u'拡張子をjpgに限定')
        #self.text = tk.Text(self)

        # キャンバス定義
        self.canvas = tk.Canvas(self, width=200, height=200, relief=tk.RIDGE, bd=2)

        # 命令ウィンドウ表示


        #
        # 各物体の位置(gridだとややこしいので、placeで直接指定する)
        # 文字など
        self.title.place(x=70, y=15)
        self.label.place(x=500, y=5)

        # エントリなど
        self.entry.place(x=500, y=30) #source
        self.entry.insert(tk.END, "開くを押して参照する")

        # ボタンなど
        self.button.place(x=650, y=5)
        self.button_qt.place(x=10, y=10)
        self.button_act.place(x=300, y=400)
        #self.button.grid(column=2, row=0, sticky=tk.E)

        # キャンバスなど
        self.canvas.place(x=500, y=60)
        self.canvas.create_text(110, 110, text=u"Not Found Image...")

        # リストボックス・スクロールなど



    # 参照ファイルコマンド
    def button_pushed(self):
        # http://spcx8.hatenablog.com/entry/2017/12/24/112528
        # ファイルの参照方法はWindowsとmacOSで異なる        
        # Windowsの場合は以下のようになる
        # fname = tkFD.askopenfilename(filetypes=[('data files','*.csv;*.txt')],initialdir=os.getcwd())
        # 参照ファイルの拡張子を絞る方法が異なるようで、Windowsの場合は'*.*'で全表示も可能

        fname = tkFD.askopenfilename(filetypes=[("jpg files","*.jpg")],initialdir=os.getcwd())
        print(fname)
        # picture_resize(self.fname)
        img_r = cv2.imread(fname)
        im_re = cv2.resize(img_r, (256, 256))
        cv2.imwrite("/Users/***/import_pic.jpg", im_re)
        # ソースコードの保存場所に気をつける

        # 以下、リサイズ後の絶対パス。なぜかはわからないが、絶対パスでないとエラーを吐く
        # ex) ~/Documents/... とするとエラー
        # 読み込み毎にリサイズされて上書きされる
        real_path = "/Users/***/import_pic.jpg"

        # パスはひみつです ;]

        self.var_entry.set(fname)

        self.img = ImageTk.PhotoImage(file=real_path)
        self.canvas.create_image(110, 110, image=self.img)


    # Exitする
    def button_quit(self):
        print("Good Bye.")
        exit()

    # test action
    def button_action(self):
        sub_win = tk.Toplevel(master=self.master)

        frame1 = tk.Frame(sub_win)
        frame1.grid()

        currencies = ('JPY', 'USD', 'EUR', 'CNY', 'MXN', 'CAD')
        v1 = tk.StringVar(value=currencies)
        lb = tk.Listbox(frame1, listvariable=v1, height=3)
        lb.grid(row=0, column=0)

        scrollbar = tk.Scrollbar(frame1, orient="v", command=lb.yview)
        lb['yscrollcommand'] = scrollbar.set
        scrollbar.grid(row=0, column=1, sticky=tk.NS)

        button = tk.Button(frame1, text="thank you", command=sub_win.destroy)
        button.grid(row=1, column=0, columnspan=2)
        button.focus_set()
        sub_win.transient(self.master)
        sub_win.grab_set()



    # チェックボックス(命令セット) 仮で10とする
    def checkbox_make(self):
        check_val = []
        check_h = []

        for n in range(int(10)):
            #BooleanVarの作成
            bl = tk.BooleanVar()
            bl.set(False)

            self.listbox.insert(x, "Meirei" + str(n+1))
            #b = tk.Checkbutton(text=u"命令" + str(n+1), variable = bl)
            #b.self.place(x=400, y=20*n + 100)

            #チェックの値を入れる
            check_val.append(bl)
            #チェックハンドルを入れる
            check_h.append(b)


# ひながた        
if __name__ == "__main__":
    root = tk.Tk()
    root.title("beta")
    root.geometry("720x480") # ウィンドウサイズ

    app = Application(master=root)
    app.mainloop()

 試したこと

py2applet --make-setup hoge.py で作成したsetup.pyを
python setup.py py2app --iconfile test.icns と実行しました。

すると以下のようにエラーが発生。

Traceback (most recent call last):
  File "setup.py", line 5, in <module>
    setup_requires=['py2app'],
 File "/anaconda3/lib/python3.6/site-packages/setuptools/__init__.py", line 129, in setup
    return distutils.core.setup(**attrs)
 ...
 RecursionError: maximum recursion depth exceeded

最大再帰数を超えているということで、こちらを参考にソースコードへ追記。
再度実行しても、同様にエラー。

そもそもsetup.pyで詰んでいるようなので、こちらを参考にsetup.pyのOPTIONSを丸ごと消してみました。

ビルドは成功して.appは作成されたのですが、こちらの方と同様のエラーが発生して、.appを実行することができません。OPTIONSを追加するとビルドできないので、どのように解決すれば良いか教えていただきたいです。

setup.pyのマニュアルを読んだのですが、理解できていません。

怪しいなと思うのは、Webから.pkgでインストールしたAnacondaが何かしら阻害しているように思えます。
次はPYTHON_PATHを編集してanacondaモジュールをインポートしないように試してみようと考えています。

 その後試したこと

PYTHON_PATHで指定しているanacondaモジュールをコメントアウトした結果、上記2つのエラーは吐かなくなりました。同様にして実行すると、.appが生成はされたのですが実行できない状況です。

.app実行時のエラー文

hoge.app Error.

以下、ビルド時のエラー文

Traceback (most recent call last):
  File "setup.py", line 6, in <module>
    version='0.0.1',
  File "/usr/local/lib/python3.6/site-packages/setuptools/__init__.py", line 129, in setup
    return distutils.core.setup(**attrs)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/distutils/dist.py", line 955, in run_commands
    self.run_command(cmd)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/distutils/dist.py", line 974, in run_command
    cmd_obj.run()
  File "/usr/local/lib/python3.6/site-packages/py2app/build_app.py", line 825, in run
    self._run()
  File "/usr/local/lib/python3.6/site-packages/py2app/build_app.py", line 1040, in _run
    self.run_normal()
  File "/usr/local/lib/python3.6/site-packages/py2app/build_app.py", line 1152, in run_normal
    self.create_binaries(py_files, pkgdirs, extensions, loader_files)
  File "/usr/local/lib/python3.6/site-packages/py2app/build_app.py", line 1512, in create_binaries
    platfiles = mm.run()
  File "/usr/local/lib/python3.6/site-packages/macholib/MachOStandalone.py", line 154, in run
    node.write(f)
  File "/usr/local/lib/python3.6/site-packages/macholib/MachO.py", line 153, in write
    header.write(f)
  File "/usr/local/lib/python3.6/site-packages/macholib/MachO.py", line 368, in write
    self.synchronize_size()
  File "/usr/local/lib/python3.6/site-packages/macholib/MachO.py", line 358, in synchronize_size
    self.low_offset, self.sizediff))
ValueError: New Mach-O header is too large to relocate in '/hoge/~/hoge.app/Contents/Resources/lib/python3.6/matplotlib/.dylibs/libpng16.16.dylib' (new size=1256, max size=1200, delta=108)


どうやらmatplotlibとmacholibがpy2appとケンカしてるみたいです。
同様のエラー #1
同様のエラー #2
このサイトを参考にしても、レベルが高すぎて追いつけません。

py2appを0.10へダウングレードすると治るかも?というのもあったのでやってみましたが、同様のエラーが発生します。

 現状

7/11更新
こちらを頼りに模索してます

 補足情報(FW/ツールのバージョンなど)

OpenCV ver3.4.1
Numpy ver1.14.3
PIL ver5.1.0

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

macOS環境がないで提案だけ。
opencvnumpyimportしていますが、質問文は画像のリサイズを行っているので、
Pillowや、tkinterPhotoImageにて画像のリサイズ処理は行ってみては。
こうすることで依存ライブラリが減ります。

img_r = Image.open(fname)
im_re = img_r.resize((256, 256))

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.87%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    6297questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 3.x

    4794questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • Tkinter

    106questions

    Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

  • Anaconda

    49questions