我尝试使用 pyinstall 将 TKinter 脚本编译为 .exe 文件,但当我打开 .exe 文件时,它显示错误。我的 TKinter 脚本有线程。以下是显示 speedtest.py 中未处理的异常的堆栈跟踪
Traceback (most recent call last):
File "speedtest.py", line 156, in <module>
ModuleNotFoundError: No module named '__builtin__'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "Speedtest.py", line 3, in <module>
from speedtest_cli import Speedtest
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 450, in exec_module
File "speedtest_cli.py", line 30, in <module>
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 450, in exec_module
File "speedtest.py", line 179, in <module>
File "speedtest.py", line 166, in __init__
AttributeError: 'NoneType' object has no attribute 'fileno'
这是我用于编译的代码:
process = subprocess.Popen(
r'pyinstaller.exe --onefile --noconsole --distpath D:\PythonProjects\Speedtest Speedtest.py',
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE,
shell=True)
output, error = process.communicate()
if error:
print(error.decode())
if output:
print(output.decode())
我试过:
- 将 --noconsole 更改为 --windowed
- 删除
stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE
删除 --noconsole 不是一个选项,我在 .exe 文件中不需要控制台
这里还有speedtest.py
from tkinter import *
from tkinter import ttk
from speedtest_cli import Speedtest
import threading
root = Tk()
root["bg"] = "#fafafa"
root.geometry("300x400")
root.title("Speedtest")
root.iconbitmap("icon.ico")
root.resizable(False, False)
style = ttk.Style()
style.configure("TButton", font=("Comic Sans MS", 20))
def speedtest():
downloadText.config(text="Download Speed:\n-")
uploadText.config(text="Upload Speed:\n-")
pingText.config(text="Ping:\n-")
st = Speedtest()
errorText.place_forget()
analyzingText.place(anchor=CENTER, relx=0.5, rely=0.92)
downloadSpeed = round(st.download() / (10 ** 6), 2)
uploadSpeed = round(st.upload() / (10 ** 6), 2)
pingSpeed = st.results.ping
downloadText.config(text="Download Speed:\n" + str(downloadSpeed) + " Mbps")
uploadText.config(text="Upload Speed:\n" + str(uploadSpeed) + " Mbps")
pingText.config(text="Ping:\n" + str(pingSpeed) + " Ms")
analyzingText.place_forget()
def speedtestChecked():
try:
speedtest()
except Exception:
analyzingText.place_forget()
errorText.place(anchor=CENTER, relx=0.5, rely=0.92)
def startSpeedtestThread():
speedtestThread = threading.Thread(target=speedtestChecked)
speedtestThread.start()
speedtestButton = ttk.Button(root, text="Start Speedtest", style="TButton", command=startSpeedtestThread)
speedtestButton.pack(side=BOTTOM, pady=60)
analyzingText = Label(text="Analyzing...", bg="#fafafa", font=("Comic Sans MS", 17))
errorText = Label(text="Error occurred!", bg="#fafafa", font=("Comic Sans MS", 17), fg="#a83636")
downloadText = Label(text="Download Speed:\n-", bg="#fafafa", font=("Comic Sans MS", 17))
uploadText = Label(text="Upload Speed:\n-", bg="#fafafa", font=("Comic Sans MS", 17))
pingText = Label(text="Ping\n-", bg="#fafafa", font=("Comic Sans MS", 17))
downloadText.place(anchor=CENTER, relx=0.5, rely=0.13)
uploadText.place(anchor=CENTER, relx=0.5, rely=0.35)
pingText.place(anchor=CENTER, relx=0.5, rely=0.57)
root.mainloop()