1

I have a TKinter application which i put together in Visual Studio Code. It runs perfectly fine in Visual Studio Code and does not freeze or anything like that. Because I want my program to run on other pcs as well, I created an .exe file using pyinstaller by running

pyinstaller --onefile -w "main.py"

This creates the desired .exe file without any problems. Sadly when put into an .exe file, my program crashes a lot, by crashing I mean that the window is not responding anymore or that the window just closes itself after some time. I don't know if this is a commom problem but I honestly don't know what to do. Apparently I don't have any problems in my code, because it runs perfectly fine in Visual Studio Code.

Is there anything I can do?

Edit 1: My window freezes around these lines of my code: I am trying to create 4 scales with a for loop:

for i in range(4):
    scale = tk.Scale(self.root, state = "disabled", from_ = 100, to = 0)
    scale.place(rely=0.2,relx=i*0.25,relwidth=0.25, relheight=0.8)
    self.scales.append(scale)

Also I try to put my scales into the list self.scales so I can work with my scales later on. The program creates the first three scales without any problem but often fails to create the 4th.

EDIT 2: I think I found a solution: Maybe the for loop is just too fast for Tkinter and it can't create the GUI items that fast, I added

time.sleep(0.1)

to my for loop, for now, this seems to work. But I dont really know if thats how its supposed to be.

EDIT 3: Nevermind, this did not solve the problem. The problem has something to do with creating the scales. I dont really know what to do.

Luca Tatas
  • 160
  • 1
  • 14
  • If you are using any external files in your application, make sure they are in the same directory as the `.exe` and if you wish to bundle the data files in your exe as well, you can use the flag `--add-data` and modify your code as stated in https://stackoverflow.com/a/13790741/14094985 as Pyinstaller unpacks all the dependencies to a temporary directory during execution. – astqx Dec 14 '20 at 11:00
  • Thanks for your answer! The only files I am using are .py files and an .ico file, the .ico file is in the same directory, so this should not be a problem. Beyond that I have used try/except whenever accessing files. – Luca Tatas Dec 14 '20 at 11:29
  • Alright, you can use the `-c` flag instead of the `-w` flag, that way the resulting executable will be in console mode, this will help you view the exact errors that are occurring before your app crashes. – astqx Dec 14 '20 at 11:47
  • pyinstaller -y -F "onefile.py" - adds a console and errors should pront on this –  Dec 14 '20 at 17:09
  • I edited my question multiple times, maybe you can have a look. – Luca Tatas Dec 14 '20 at 17:45

1 Answers1

0

Check out Logging, and the tutorial that comes with. After formatting to write to a file, you can put a few logging.info() here and there which can help determine the root cause of your error.

import logging

logging.basicConfig(filename='log.txt',
                    filemode='a',
                    format='%(asctime)s %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    level=logging.INFO)

def my_func(x, y):

    logging.info('Accessing Function: my_func()')

    z = x + y

    logging.info(f'Function myfunc() Successfully Completed, Variable Values: {x}, {y}, {z}')


my_func(2, 7)

Now you have a handy log.txt file which you can diagnose.

EDIT

Using the lines of code you provided, I tried out the following:

import tkinter as tk


class Application(tk.Frame):
    def __init__(self, root=None):
        super().__init__(root)
        self.root = root
        self.root.geometry('720x450')
        self.pack()
        self.scales = []
        self.create_scale()

    def create_scale(self):
        for i in range(4):
            scale = tk.Scale(self.root, state="disabled", from_=100, to=0)
            scale.place(rely=0.2, relx=i*0.25, relwidth=0.25, relheight=0.8)
            self.scales.append(scale)


gui = tk.Tk()
app = Application(root=gui)
app.mainloop()

I made an exe with PyInstaller 4.1, Python 3.9 and all four scales are properly produced on my screen so the problem isn't with those specific lines of code but how they interact with the rest of your code.

I can try finding out the root of your problem but I would need to see your full code or a minimal, reproducible example that successfully mimics the same problem you have.

Andrew Stone
  • 1,000
  • 1
  • 7
  • 17
  • Thanks for your answer. I actually wrote a logging funciton myself because I didnt know this existed. I edited my question so you can see what I am working with – Luca Tatas Dec 14 '20 at 17:01
  • I edited my question multiple times, maybe you can have a look. – Luca Tatas Dec 14 '20 at 17:45
  • Sorry for the late reply, I went to bed right after surfing this site for a bit. Anyways, I updated my answer, hope it helps. – Andrew Stone Dec 15 '20 at 02:29
  • 1
    Thanks for your huge effort! I got it to work farily ok by using ttk.scales. But I have a question in general: Is it recommended to do .mainloop() inside of outside of the class you are using as your GUI? I see that you are doing .mainloop() not in __init__, but thats what I am doing. Is there any difference? – Luca Tatas Dec 15 '20 at 10:04
  • You're welcome! Glad to hear you found a solution and wow that's pretty neat I didn't even think to try putting `.mainloop()` inside the `__init__` section. The examples I saw put `.mainloop()` outside of the class so that's why I put mine there. I'm assuming yours is the very last line of the `__init__` section, in which case yeah that totally works just as well because you are calling all your functions and setting up your gui before calling `.mainloop()` and that's all that matters really. – Andrew Stone Dec 15 '20 at 10:30
  • Yeah thats exactly what Im doing! :) – Luca Tatas Dec 15 '20 at 11:06