[Python] GUI wrapping speedtest_cli does not work when packaged with pyinstaller

Discussão em 'Python' iniciado por Stack, Fevereiro 11, 2025.

  1. Stack

    Stack Membro Participativo

    I tried to compile a TKinter script into .exe file with pyinstall, but when I open the .exe file it shows an error. My TKinter script has threading. Here's a stack trace showing unhandled exception in 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'


    Also here's the code I used for compilation:

    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())


    I tried:

    • Changing --noconsole to --windowed
    • Deleting stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE

    Deleting --noconsole is not an option, I don't need a console while in .exe file

    Also here is 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()

    Continue reading...

Compartilhe esta Página