Python py2app/PIL使MacOS在不同机器上注销时崩溃的问题

Python py2app/PIL使MacOS在不同机器上注销时崩溃的问题,python,tkinter,python-imaging-library,python-3.8,py2app,Python,Tkinter,Python Imaging Library,Python 3.8,Py2app,这基本上是一个桌面应用程序,用于拍摄区域屏幕截图并使用递增的文件名保存到选定文件夹。没有什么特别的,只使用PIL和Tkinter LIB 如果我正在运行开发中的.py或.app文件,一切都很好 机器 在没有lib append的任何其他计算机上运行.py文件会导致找不到PIL模块 IDE上的错误 以任何方式运行.app都会使应用程序在注销时崩溃 屏幕 我尝试了几种方法来解决这个问题;比如--includes=PIL,添加打包信息选项,将实际库文件添加到.app library files文件

这基本上是一个桌面应用程序,用于拍摄区域屏幕截图并使用递增的文件名保存到选定文件夹。没有什么特别的,只使用PIL和Tkinter LIB

  • 如果我正在运行开发中的.py或.app文件,一切都很好 机器
  • 在没有lib append的任何其他计算机上运行.py文件会导致找不到PIL模块 IDE上的错误
  • 以任何方式运行.app都会使应用程序在注销时崩溃 屏幕
我尝试了几种方法来解决这个问题;比如--includes=PIL,添加打包信息选项,将实际库文件添加到.app library files文件夹,附加库路径

在过去的两天里,我一直在为这个问题绞尽脑汁,我觉得我在绕圈子,在这个问题上没有太多的优先权

以下是文件:

main.py

import sys
sys.path.append("lib/python3.8/") # latest attempt to show PIL files. 
import tkinter as tk
from tkinter import filedialog, simpledialog
from tkinter import ttk

from PIL import ImageTk, ImageGrab, ImageEnhance

# if platform() == 'Darwin':  # How Mac OS X is identified by Python
#     system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
#     subprocess.call(["/usr/bin/osascript", "-e", 'tell app "Finder" to set frontmost of process "Python" to true'])

root = tk.Tk()
root.resizable(0, 0)
root.geometry("210x400+0+0")
root.title("Erkan Ulu Crop Aracı")
root.iconbitmap("bitmap.ico")
root.configure(bg="#1F2020")

# logo = tk.PhotoImage(file="app-logo.png")
logo = tk.PhotoImage(file="appicon.png")

# Theme Options
path_to_theme = "./awthemes-9.4.2/"
root.tk.call('lappend', 'auto_path', path_to_theme)
root.tk.call('package', 'require', 'awdark')
style = ttk.Style()
style.theme_use("awdark")

# Label Config
style.configure("TLabel",
                padding=(10,10,10,10),
                justify=tk.CENTER,
                font="Open-sans 10")

# Button Config
style.configure("TButton",
                width=20,
                justify=tk.CENTER,
                font="Open-sans 10 bold")

folderPath = tk.StringVar()
folderPath_View = tk.StringVar(value="Başlamadan Önce\nLütfen Klasör Seçiniz.")

file_name = 1
question_no = tk.StringVar(value="1")
question_text = tk.StringVar(value="Çekilen Soru No: ")

default_path = "~/Desktop"


def set_file_name():
    global file_name
    file_name = simpledialog.askinteger("Soru No:", "Başlanacak soru numarasını yazınız.", parent=root)
    question_no.set(file_name)
    print("Sayı numarası ayarlandı")


# def set_pre_file_name():
#   global file_name
#   file_name = simpledialog.askinteger("Soru Öncesi İsim", "Soru İsminin Başına Yazılaca ", parent=root)
#   question_no.set(file_name)
#   print("Soru Öncesi İsim Ayarlandı")


def undo_image(event):
    global file_name
    file_name -= 1
    area_sel(event)
    print("Görsel tekrar çekiliyor")


def reset(event):
    global file_name
    file_name = 1
    print("Sıfırlandı")
    return file_name


def set_folder_name():
    folder_selected = filedialog.askdirectory(initialdir="~/Desktop")
    folderPath.set(folder_selected)
    view_path = str(folder_selected)
    X_path = view_path.rsplit("/", 1)[1]
    folderPath_View.set(X_path)
    root.update()
    global file_name
    file_name = 1
    question_no.set(file_name)
    print("Klasör Ayarlandı: " + folder_selected)


def area_sel(event):
    x1 = y1 = x2 = y2 = 0
    roi_image = None


def on_mouse_down(event):
    nonlocal x1, y1
    x1, y1 = event.x, event.y
    canvas.create_rectangle(x1, y1, x1, y1, outline='red', tag='roi')


def on_mouse_move(event):
    nonlocal roi_image, x2, y2
    x2, y2 = event.x, event.y
    canvas.delete('roi-image')  # remove old overlay image
    roi_image = image.crop((x1, y1, x2, y2))  # get the image of selected region
    canvas.image = ImageTk.PhotoImage(roi_image)
    canvas.create_image(x1, y1, image=canvas.image, tag=('roi-image'), anchor='nw')
    canvas.coords('roi', x1, y1, x2, y2)
    # make sure the select rectangle is on top of the overlay image
    canvas.lift('roi')

    root.withdraw()
    image = ImageGrab.grab()
    bgimage = ImageEnhance.Brightness(image).enhance(0.25)
    win = tk.Toplevel()
    win.attributes('-fullscreen', 1)
    win.attributes('-topmost', 1)
    canvas = tk.Canvas(win, highlightthickness=0)
    canvas.pack(fill='both', expand=1)
    tkimage = ImageTk.PhotoImage(bgimage)
    canvas.create_image(0, 0, image=tkimage, anchor='nw', tag='images')
    win.bind('<ButtonPress-1>', on_mouse_down)
    win.bind('<B1-Motion>', on_mouse_move)
    win.bind('<ButtonRelease-1>', lambda e: win.destroy())
    win.bind('<Escape>', lambda e: win.destroy())
    win.focus_force()
    win.grab_set()
    win.wait_window(win)
    root.deiconify()
    if roi_image:
        global file_name
        folder_name = folderPath.get()
        # folder_name = "/Users/anil/Desktop/testfolder"
        convert_img = roi_image.convert("RGB")
        save_path = folder_name + "/" + str(file_name) + ".jpeg"
        file_name += 1
        question_no.set(file_name)
        save_format = "JPEG"
        convert_img.save(save_path, save_format)
        # show_image(convert_img, file_name-1)
        # root.focus_force()
        # root.focus_set()
        # root.mainloop()
        print("Soru Çekildi")

        root.update()  # new_image_question()

#PADDING = (SOLA, YUKARI, SAĞA, AŞAĞI)
ttk.Label(root, image=logo).pack()
ttk.Button(root, text="Klasör Seç\nBaşla", command=set_folder_name).pack()
ttk.Label(root, textvariable=folderPath_View, font="Open-sans 12", padding=(0,10,0,20)).pack()
ttk.Button(root, text="Başlanacak Soru\nNumarasını Seç", command=set_file_name).pack()
ttk.Label(root, text="Çekilecek Soru No:",padding=(0,10,0,0)).pack()
ttk.Label(root, textvariable=question_no,padding=(0,0,0,0), font="Open-sans 12").pack()
ttk.Label(root, text="Soru Ekle = S Tuşu\nSoruyu Tekrar Çek = T Tuşu").pack()

root.bind('<Key-s>', area_sel)
root.bind('<Key-t>', undo_image)
root.bind('<Key-Escape>', reset)

root.mainloop()
"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['main.py']
DATA_FILES = ["logo.png","bitmap.ico","awthemes-9.4.2","appicon.icns","appicon.png"]
OPTIONS = {
    'iconfile':'appicon.icns',
    'argv_emulation': True,
    'site_packages': True,
    'use_pythonpath': True,
    'packages': ['PIL', 'tkinter'],
    'includes': ['PIL','tkinter','ImageTk']
}

setup(
    app=APP,
    data_files=DATA_FILES,
    version="1",
    name="Crop Tool",
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
    install_requires=["Pillow"]
)
编译错误:

Modules not found (unconditional imports):
 * PyQt5.QBuffer (PyQt5.QtCore, PyQt5.QtGui)
 * PyQt5.QIODevice (PyQt5.QtCore, PyQt5.QtGui)
 * PySide2.QBuffer (PySide2.QtCore, PySide2.QtGui)
 * PySide2.QIODevice (PySide2.QtCore, PySide2.QtGui)
 * _gdbm (dbm.gnu)
 * _overlapped (asyncio.windows_events)
 * cffi (PIL.Image, PIL.PyAccess)
 * cffi.FFI (PIL.Image)
 * com (com.sun.jna)
 * com.jna (com.sun)
 * com.sun (com.sun.jna.platform)
 * numpy (PIL.ImageFilter)
 * olefile (PIL.FpxImagePlugin, PIL.MicImagePlugin)
 * ordereddict (pkg_resources._vendor.pyparsing)
 * win32com (win32com)
 * win32com.shell (win32com.shell)
 * win32com.shellcon (win32com.shell)

Modules not found (conditional imports):
 * Image (/Users/anil/PycharmProjects/ULUCrop-V2/venv/lib/python3.8/site-packages/py2app/recipes/PIL/prescript.py)
 * PySide2 (PIL.ImageQt)
 * PySide2.QtGui (PIL.ImageQt)
 * StringIO (pkg_resources._vendor.six)
 * cffi (PIL.ImageTk)
 * com (pkg_resources._vendor.appdirs)
 * com.sun.jna (pkg_resources._vendor.appdirs)
 * com.sun.jna.platform (pkg_resources._vendor.appdirs)
 * win32com (pkg_resources._vendor.appdirs)
 * win32com.shell (pkg_resources._vendor.appdirs)

未找到
模块
-消息大多无害

根据您的描述(在安装了所有库的开发机器上,一切都运行良好,但在没有库的另一台计算机上不工作),您可能正在使用带有选项
-A
--alias
(即
python setup.py py2app-A
)的py2app,因此,创建不包含库的开发版本(请参见)。如果是这种情况,请删除
-A
选项并仅使用

python setup.py py2app
生成包含所有库的.app


如果您没有使用
-A
选项,并且仍然收到有关缺少库的错误消息,请复制并粘贴完整的错误消息;它可能包含额外的信息,以便进一步帮助您。

您的代码很长。请始终提供帮助,以便其他人更容易理解您的问题并帮助您。