1

Tkinter will open a window with buttons, like I want, when I am not trying to import a variable from another Python program I wrote. But when I do, Tkinter will not open. When I use from my_program import variable, does it run the program first? I have a while True loop in the other program. However, I am using Tkinter to make buttons that run the other program then stop it.

from tkinter import *
import os
import signal
import threading   
from my_program import variable
while True:
     my code

I tried removing the from my_program import variable line, which then causes it to work again.

2
  • 2
    Yes, importing from a program runs the program first, that's how it works. You shouldn't have an infinite loop in a module you're importing from. Put that in a function that you can call from the main script.
    – Barmar
    Commented Aug 15, 2024 at 20:58
  • 3
    If the loop should only run when you run my_program.py directly, not when importing, it should be in the if __name__ == '__main__': block. See stackoverflow.com/questions/419163/what-does-if-name-main-do/…
    – Barmar
    Commented Aug 15, 2024 at 20:59

1 Answer 1

1

Yes, as @Barmar mentioned, importing anything from a file will first run that file. If you just want import something without running your file, you should put the infinite loop in my_program in an if-main-block.

if __name__ == "__main__":
    while True:
        ...

This will make it only being executed when you run only the my_program file, like using python3 my_program.py.

However, if you want to run that infinite loop while having the tkinter window open, you need to understand that the tkinter window itself gets executed in an infinite loop, and your Python code is busy running that window and can't do anything else at the same time. You probably have a line like window.mainloop() in your code, this is where your code is "stuck" while executing your script.

I don't know what exactly you need that infinite loop for, but if you want it to run simultaneously with your Tkinter window, you basically have two options for doing this.

  1. Manually update your window in your infinite loop: Replace your window.mainloop() instruction with that:
while True:
    window.update()
    window.update_idletasks()
    
    (your custom code here)

The update() and update_idletasks() methods basically just do the same things that mainloop() does, but only a single time. This option is good if your custom code doesn't take long to execute. However, if it does take a long time to execute, notice that your window will only be updated when window.update() is called, so while your custom code is running, you won't be able to click on buttons or anything.

  1. Run your custom code in a seperate thread: You can also use multithreading to run your code in parallel to the tkinter window. Put your custom infinite loop in a function like this:
def my_custom_loop():
    while True:
        my code

Then, create a thread that will call that function:

from threading import Thread

my_custom_thread = Thread(target = my_custom_loop)

Before your window.mainloop() line, you can then insert my_custom_thread.start() to start running it in the background.

However, this could be overkill depending on what you want to achieve with your custom code. If you need more help you should be more specific about what "my code" should actually do.

2
  • 3
    Those aren't the only 2 options. This is method isn't mentioned but is the advised way to run code along side tkinter's mainloop. Other points: keep in mind that tkinter isn't really thread-safe, update_idletasks() is useless if you are going to call update() right before it.
    – TheLizzard
    Commented Aug 15, 2024 at 22:39
  • 2
    Ok I guess you're right, use the after method if you want to run something in parallel woth your app. As it's a builtin feature of tkinter I guess it's the best you can do. Commented Aug 16, 2024 at 7:18

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.