Why is my tkinter program exiting shortly after it's started? - python

I've started learning Tkinter(some of you may know why). So I made a simple program by following a tutorial:
from tkinter import *
root = Tk()
myLabel1 = Label(root, text = "Hello Mushroom world!")
myLabel2 = Label(root, text = "Hello Mario world!")
myLabel1.grid(row = 0, column = 0)
myLabel2.grid(row = 1, column = 0)
root.mainloop()
When I runed it, it showed me a blank window for less than a second and then it disappears (by the way, the window was as big as a restore down window but I think it was supposed to be small because I didn't specify the size of the window). I'm on Windows 10 using WSL2 and I run my code on command prompt because it's a GUI. I would like to know what is causing this bug. Thanks!

You can add a button that destroys the window, therefore quits the App.
from tkinter import *
root = Tk()
def close_window():
root.destroy()
myLabel1 = Label(root, text = "Hello Mushroom world!")
myLabel2 = Label(root, text = "Hello Mario world!")
button = Button (text = "Close", command = close_window)
myLabel1.grid(row = 0, column = 0)
myLabel2.grid(row = 1, column = 0)
button.grid(row = 2, column = 0)
root.mainloop()
You can simplify by instead of using the close_window function, just type root.destroy for the command parameter.
EDIT
After editing the original question, it turns out the OP's program quit after ~a second, and he wanted to know why does that happen, instead of another way to quit. The error seems to be in his environment. After changing to the original python IDE/IDLE, the code works fine.
Turns out he named his file tkinter.py, that caused the bug.

Related

I'm trying to make an image a button, using python tkinter. However, the image button only shows up when I put a character on the line below

I have created an image as a button. Upon opening a pop put window, I want the image button to be in a specific place (I've used the grid method). However, the button only appears when I include a character (any character) in the line below the button code.
When the character is included, the image appears and the function called by the pressing of it works perfectly. I do get an error message when the pop out window initially appears though.
Here is my code:
def eastereggtxt1():
function works fine so don't worry about this
function
img = PhotoImage(file = r'pathtoimage.png')
imgbutn = Button(EntryWindow,
image = img, borderwidth = 0,
command = eastereggtxt1)
imgbutn.grid(row = 18, column = 7)
r
The image/button only shows up if I run it with the above character "r" included. However, the character can be any letter really. without it, the image doesn't show up.
Any idea why this is happening?
Assuming that your code is this:
from tkinter import *
from tkinter.ttk import *
root = Tk()
def eastereggtxt1():
print("Easter Eggs!")
image = PhotoImage(file = r'easter_eggs.png') # I use easter_eggs as an example
image_button = Button(root, image = image, command = eastereggtxt1)
image_button.grid(row = 18, column = 7)
mainloop() # I just know that you can just do mainloop(), but it's not effective
I tryed the code, it works fine, but when I try to replace r with something else, (Example: l,p,s), an error occured:
PS C:\Users\user#1> python -u "D:\Test\test1.py"
File "D:\Test\test1.py", line 9
img = PhotoImage(file = s'easter_eggs')
^
SyntaxError: invalid syntax
It refers that the code can't use any other character than r.
Also you mentioned:
The image/button only shows up if I run it with the above character "r" included.
I think your OS doesn't support without the character r? If this is wrong, please tell me in the comments.
Peace :D
You can use a label instead of a button. That could be a good option.
But you'll need to change a few lines of code.
In the eastereggtext1() function, pass an argument event.
Example:
def eastereggtext(event):
# function code here...
Then, remove the button and add an image.
imgbutn = Label(root, image=img)
imgbutn.grid(row = 18, column = 7)
Then, bind the label to mouse click.
imgbutn.bind("<Button-1>", eastereggtext1)
For more info about tkinter bindings: Python | Binding function in Tkinter
So here's the full code:
from tkinter import Tk, Button, PhotoImage
# other modules you need to import
root = Tk()
root.title("Title of the window")
def eastereggtext1(event):
# function code here....
img = PhotoImage(file = 'image_path.png')
imgbutn = Label(root, image=img)
imgbutn.grid(row = 18, column = 7)
imgbutn.bind("<Button-1>", eastereggtext1)
root.mainloop()

Tkinter window closing, but python script stays running

I've tried a variety of things but can't seem to figure this out.
Here's a general overview of my program, which takes an Excel file as an import and outputs a .pdf of charts:
Ask user to enter a file name for the outputted file (using Tkinter textbox input)
Ask user to select the input file (using askopenfilename)
Does a bunch of work with Pandas to analyze data, then plots it with matplotlib and PdfPages
Displays a message with Tkinter that says the file was outputted successfully, along with a "Exit" button, which should end the program, but does not.
Here's #1 (separately, I'm wondering how I could modify this code to accept the "Enter" button instead of having to physically click the button):
root = tk.Tk()
root.title("Enter a file name for the report")
def getOutputFileName():
global outputFileName
outputFileName = textBox.get("1.0",'end-1c')
print(outputFileName)
root.quit()
textBox = Text(root, height=1, width = 25)
textBox.pack()
buttonCommit = Button(root, height=5, width=50, text="After entering a file name, click here.", command=lambda: getOutputFileName())
buttonCommit.pack()
root.mainloop()
root.withdraw()
Here's #2:
filetypes=[("Excel files", ".xlsx .xls")]
file_path = fd.askopenfilename(filetypes=filetypes, title = 'Open the Excel input file')
df = pd.read_excel(file_path) ## Start of Pandas code
#3 shouldn't be relevant as it doesn't use Tkinter whatsoever (plus the .pdf is exporting correctly), so here's #4:
window = tk.Toplevel() ## Here I tried using root = tk.Tk() but learned that Toplevel() needs to be used for windows after the first?
window.Title = "Success!"
window.geometry("250x170")
T = Text(window, height = 5, width = 52)
successText = "Report successfully generated. The .pdf file was saved to the same location from which you ran this program. You may close the program now."
b1 = Button(window, text = "Exit", command = window.destroy) ## This button DOES close the window, but doesn't close the entire program (i.e. my IDE stays running the script until I force stop)
T.pack()
b1.pack()
T.insert(tk.END, successText)
tk.mainloop()
print("End of program.") ## this is for testing - the program never gets here.
Any advice would be amazing. Thank you.

Tkinter window opens after code is finished

I'm just beginning to get the basic funtions of the soundcard python module to work. However I cannot make my tkinter window show up first and wait until I press the run button to exicute the "def run()" code. It always does the "def run()" code first and then opens the window. What am I doing wrong?
from tkinter import *
import soundcard as sc
window = Tk()
window.geometry("500x500")
window.title("Virtual Soundcard")
default_speaker = sc.default_speaker()
default_mic = sc.default_microphone()
def run():
with default_mic.recorder(samplerate=44100) as mic, \
default_speaker.player(samplerate=44100) as sp:
for val in range(100):
data = mic.record(numframes=None)
sp.play(data)
RunButton = Button(window, text ="Run", command = run())
RunButton.pack()
RunButton.place(x = 100, y = 250)
window.mainloop()
Change RunButton = Button(window, text ="Run", command = run()) to
RunButton = Button(window, text ="Run", command = run)
Basically remove the () for the command argument, with the () your calling the function even before pressing the button, ie, while code execution.
Hope this solved the error. Do let me know if any doubts or errors.
Cheers

No errors but wont run

So I have this code:
try:
# for Python2
from Tkinter import *
except ImportError:
# for Python3
from tkinter import *
class Injector():
def __openInjector(self):
root = Tk()
root.geometry('600x400')
root.title('Toontown Rewritten Injector')
root.resizable(False, False)
def __init__(self):
self.code = ''
self.__openInjector()
def runInjectorCode(self):
exec(self.code.get(1.0, 'end'), globals())
def __openInjector(self):
root = Tk()
root.geometry('600x400')
root.title('Toontown Rewritten Injector')
root.resizable(False, False)
frame = Frame(root)
self.code = Text(frame, width=70, height=20)
self.code.pack(side='left')
Button(root, text='Inject!', command=self.runInjectorCode).pack()
scroll = Scrollbar(frame)
scroll.pack(fill='y', side='right')
scroll.config(command=self.code.yview)
self.code.config(yscrollcommand=scroll.set)
frame.pack(fill='y')
Injector()
In the IDLE console it works fine and does everthing I want it to do. But whenever I run the .py file on my Desktop. The black window appears, then just closes and nothing happens. Any help?
First, you have two methods in your class with the same name. The first one gets overwritten by the second one. At the end of that second one, you need the following line:
root.mainloop()
This will actually run the GUI. It's needed when running from a script, but not when running within the interactive interpreter.
Add it at the end of the second __openInjector:
...
self.code.config(yscrollcommand=scroll.set)
frame.pack(fill='y')
root.mainloop()
At the end of your second __openInjector method, add the line: root.mainloop().
This is necessary for Tkinter to run your code. mainloop is really nothing more than an infinite loop that waits for events. An event may be a user interaction, such as clicking a button.
My guess is you don't need mainloop when running interactively for purely convenience reasons.

"execfile" doesn't work properly

I'm trying to make a launcher for my Python program with Tkinter. I used the execfile function, and fortunately it opened the target GUI. However, none of the buttons would work, and it would say the global variable most functions reference isn't defined.
The code to launch the program:
def launch():
execfile("gui.py")
That works. The base code for the target program:
from Tkinter import *
gui = Tk()
gui.title("This is a GUI")
EDIT:
Example of a button:
def buttonWin():
buttonWindow = Toplevel(gui)
button = Button(buttonWindow, text = "Button", width = 10, command = None)
button.pack()
When it references that 'gui' variable for Toplevel, it comes up with an error. I tried defining the 'gui' variable in the Launcher script, but that only caused the target script to open first, instead of the Launcher:
gui = Tk()
launcher = Tk()
launcher.title("Launcher")
def launch():
return execfile("gui.py")
launchButton = Button(launcher, text = "Launch", width = 10, command = launch)
When I try pressing one of this program's buttons, I get a NameError:
$NameError: Global variable 'gui' is not defined$
Also this is in Python 2.7.5.
Thank you anyone who answers, and sorry for any errors with the code blocks; I'm new.
The problem is that you have structured the Tkinter program incorrectly.
In "gui.py" you should have something like:
from Tkinter import *
gui= Tk()
gui.mainloop()
You can add buttons to perform functions and customize it:
from Tkinter import *
gui = Tk()
gui.title("This is a GUI")
def launch():
execfile("gui.py")
launchbutton = Button(gui, text='Launch Program', command=launch)
launchbutton.pack()
gui.mainloop()
I think with your function buttonWin you were trying to do what is normally handled by a class; see unutbu's answer here.
I'm not sure if I've addressed your problem, but this should be a start.

Categories