simple Tkinter program - window vanishes after clicking button - maintop problem? - python

Coders,
I guess I have a newbie question: my windows disappears when I click on a button. If I put in root.mainloop() as last line in the buttonClicked-function, then the program is fine - but it looks not right...what is wrong here?
import tkinter as tk
def buttonClicked(event):
print(tf1.get())
tf1Content.set("button clicked")
# root.mainloop() ... would work
root = tk.Tk()
frame = tk.Frame(root, relief="ridge", borderwidth=2)
frame.pack(fill="both",expand=1)
label = tk.Label(frame, text="Input:")
label.pack(expand=1)
tf1Content = tk.StringVar()
tf1 = tk.Entry(frame, text="input here", textvariable=tf1Content)
tf1.pack(expand=1)
bOk = tk.Button(frame,text="OK",command=root.destroy)
bOk.bind("<Button-1>", buttonClicked)
bOk.widget = "bOK"
bOk.pack(side="bottom")
tf1.focus()
root.mainloop()

It turns out that you just copied this line:
bOk = tk.Button(frame,text="OK",command=root.destroy)
which binds a call to root.destroy() to the button press.
The fix is to just remove the command parameter:
bOk = tk.Button(frame,text="OK")

Related

Returning values from entry's when pressing a button using Tkinter

I am writing a program that requires two values (from 2 entries) to be called when a button is pressed. I simplified to code to try to isolate the problem. For some reason the program is not behaving how I want it to. When the button is pressed, the output is "A=" and then if i click the button a second time I get ""A=entry1 B=entry2 A=". I have been trying to figure out the problem for hours now, please help.
import tkinter as tk
def button_function():
A = entry1.get()
print('A=', A)
B= entry2.get()
print('B=', B)
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()
entry1 = tk.Entry(root)
entry1.place(relwidth=0.5, relheight=0.5)
entry2 = tk.Entry(root)
entry2.place(rely=0.5, relwidth=0.5, relheight=0.5)
button = tk.Button(root, text = "confirm", command= button_function)
button.place(relx=0.5, relwidth=0.5, relheight=1)
root.mainloop()
You just need to change command=button_function() to command=button_function, then it will work perfectly!

How to display text on a new window Tkinter?

I've started learning Tkinter on Python few weeks ago and wanted to create a Guess Game. But unfortunately I ran into a problem, with this code the text for the rules ( in the function Rules; text='Here are the rules... ) doesn't appear on the window ( rule_window).
window = Tk()
window.title("Guessing Game")
welcome = Label(window,text="Welcome To The Guessing Game!",background="black",foreground="white")
welcome.grid(row=0,column=0,columnspan=3)
def Rules():
rule_window = Tk()
rule_window = rule_window.title("The Rules")
the_rules = Label(rule_window, text='Here are the rules...', foreground="black")
the_rules.grid(row=0,column=0,columnspan=3)
rule_window.mainloop()
rules = Button(window,text="Rules",command=Rules)
rules.grid(row=1,column=0,columnspan=1)
window.mainloop()
Does anyone know how to solve this problem?
In your code you reset whatever rule_window is to a string (in this line: rule_window = rule_window.title(...))
Try this:
from import tkinter *
window = Tk()
window.title("Guessing Game")
welcome = Label(window, text="Welcome To The Guessing Game!", background="black", foreground="white")
welcome.grid(row=0, column=0, columnspan=3)
def Rules():
rule_window = Toplevel(window)
rule_window.title("The Rules")
the_rules = Label(rule_window, text="Here are the rules...", foreground="black")
the_rules.grid(row=0, column=0, columnspan=3)
rules = Button(window, text="Rules", command=Rules)
rules.grid(row=1, column=0, columnspan=1)
window.mainloop()
When you want to have 2 windows that are responsive at the same time you can use tkinter.Toplevel().
In your code, you have initialized the new instances of the Tkinter frame so, instead of you can create a top-level Window. What TopLevel Window does, generally creates a popup window kind of thing in the application. You can also trigger the Tkinter button to open the new window.
from tkinter import *
from tkinter import ttk
#Create an instance of tkinter window
root= Tk()
root.geometry("600x450")
#Define a function
def open_new():
#Create a TopLevel window
new_win= Toplevel(root)
new_win.title("My New Window")
#Set the geometry
new_win.geometry("600x250")
Label(new_win, text="Hello There!",font=('Georgia 15 bold')).pack(pady=30)
#Create a Button in main Window
btn= ttk.Button(root, text="New Window",command=open_new)
btn.pack()
root.mainloop()

Why is Tkinter not displaying Button?

import Tkinter as ass
root = ass.Tk()
frame = ass.Frame(root)
button1 = ass.Button(frame, command=button1(), text='Kushagra', width=50, height=40)
button1.pack(side=ass.LEFT)
root.mainloop()
button1() is a function I made which i don't think is relevant. After I run this all I get is a blank window. How do I fix this?
You didn't pack the frame widget after creating the frame. The below is the edited code
import tkinter as ass
root = ass.Tk()
frame = ass.Frame(root)
frame.pack()
button1 = ass.Button(frame, text="QUIT")
button1.pack(side=ass.LEFT)
root.mainloop()
You have to pack the frame if you want it to be displayed. This will let the button to be shown but the function button1() won't work as you want because it would be called when it is given to the Button as a command, As you have used parenthesis () after giving it to the button as a command. You just need to remove those parentheses.
Like this:
import tkinter as ass
def button1():
return
root = ass.Tk()
frame = ass.Frame(root)
frame.pack()
button1 = ass.Button(frame, command=button1, text='Kushagra', width=50, height=40)
button1.pack(side=ass.LEFT)
root.mainloop()
And if you need to pass arguments to any function then you should use lambda before giving it as a command to any Button.
Like this:
import tkinter as ass
def test(a):
print(a)
root = ass.Tk()
frame = ass.Frame(root)
frame.pack()
button1 = ass.Button(frame, command=lambda: test(1), text='Kushagra', width=50, height=40)
button1.pack(side=ass.LEFT)
root.mainloop()

Menu floats above menu button

So to begin with here is my code:
from Tkinter import *
def hello():
print "Hello"
root = Tk()
root.attributes('-fullscreen', 1)
icons = []
icons.append(PhotoImage(file="Icons\start.gif"))
icons.append(PhotoImage(file="Icons\quit.gif"))
icons.append(PhotoImage(file="Icons\save.gif"))
icons.append(PhotoImage(file="Icons\load.gif"))
icons.append(PhotoImage(file="Icons\Next.gif"))
screensizex = root.winfo_screenwidth()
screensizey = root.winfo_screenheight()
mainframe = Frame(root, height=(screensizey-(screensizey/20)), width=screensizex, bg="#50a9ad")
mainframe.grid(row=0)
menuframe = Frame(root, height=(screensizey/20), width=screensizex)
menuframe.grid(row=1, sticky="w")
startmenu = Menubutton ( menuframe, text="Start", image=icons[0], compound = LEFT, relief=RAISED,
direction="above")
startmenu.grid(row=0, column=0)
startmenu.place(relx=0.03, rely=0.5, anchor=CENTER)
startmenu.menu = Menu(startmenu, tearoff=0)
startmenu["menu"] = startmenu.menu
startmenu.configure(font=("Arial", 8, "bold"))
startmenu.menu.add_command(label="Next Day", image = icons[4], compound = LEFT, command=hello)
startmenu.menu.add_separator()
startmenu.menu.add_command(label="Save", image = icons[2], compound = LEFT, command=hello)
startmenu.menu.add_command(label="Load", image = icons[3], compound = LEFT, command=hello)
startmenu.menu.add_separator()
startmenu.menu.add_command(label="Quit", image = icons[1], compound = LEFT, command=root.quit)
startmenu.menu.configure(font=("Arial", 8))
root.mainloop()
And here is what I get:
GUI
As you can see the menu "Floats" above the menu button instead of just being above it.
I am not sure of what causes that but I can't figure out how to fix it. I am sure it's something pretty simple but I am a beginner with Python....
Thanks in advance for your help.
The problem seems to be with putting the menu button on the absolute bottom. Here is near minimal code, with menu button one 'line' up from bottom, that works with 3.6 (tk 8.6) on Win10
import tkinter as tk
root = tk.Tk()
root.attributes('-fullscreen', 1)
tk.Button(root, text='Close', command=root.destroy).pack()
mb = tk.Menubutton(root, text='Menu', direction='above')
#mb.pack(side='bottom')
tk.Label(root, text='Filler2').pack(side='bottom')
mb.pack(side='bottom')
tk.Label(root, text='Filler1').pack(side='bottom')
menu = tk.Menu(mb, tearoff=0)
menu.add_command(label='Popup', command=lambda:print('hello'))
mb['menu'] = menu
Popup is on top of Filler1. Move the bottom down to the bottom (by commenting and uncommenting pack lines) and popup is in same place, leaving a gap. I tried using a ttk Menubutton instead and got the same behavior. I then went to the official Tk docs and discovered the 'flush' direction which puts the box 'over' the button. For tk, this means means 'on top of so as to cover the button'. For ttk, it means 'flush against the top, leaving the button exposed', which is what you want. So the solution, as least on Windows with tk 8.6 is to create the button with
mb = ttk.Menubutton(root, text='Menu', direction='flush')

How to make a button open a new window?

I am making a simple GUI that starts with a main menu them the user can click a button to proceed to a new window which has a picture of a keyboard and the user can press key on their keyboard to play the paino. Right now I cant figure out how to make a button that when pressed closes the main menu (labeled mainMenu()) and open the game menu (playGame).
import tkinter
from tkinter import *
class mainMenu:
def _init_(self, master):
frame = Frame(master)
frame.pack()
self.quitButton = Button(frame, text = "Quit", command = frame.quit)
self.quitButton.pack(side = LEFT)
self.proceedButton = Button(frame, text = "Play", command = playGame)
self.proceedButton.pack(side = LEFT)
def playGame(self):
frame.quit
gameMenu()
def gameMenu(self):
root = Tk()
b = mainMenu(root)
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomeFrame.pack(side = BOTTOM)
photo = PhotoImage(file = "piano.png")
label = Label(root, image = photo)
label.pack()
root.mainloop()
You'll have to forgive me for removing your class but I've never personally worked with classes in python before. However I seem to have you code working to some degree.
import tkinter
from tkinter import *
def playGame():
frame.quit
gameMenu()
def gameMenu():
b = mainMenu(root)
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side = BOTTOM)
photo = PhotoImage(file = "piano.png")
label = Label(root, image = photo)
label.pack()
root=Tk()
frame = Frame(root)
frame.pack()
quitButton = Button(frame, text = "Quit", command = frame.quit)
quitButton.pack(side = LEFT)
proceedButton = Button(frame, text = "Play", command = playGame)
proceedButton.pack(side = LEFT)
root.mainloop()
The main problem you had was that you were using both root and master. When declaring the main window in tkinter you normally use either root = Tk() or master = Tk() either one is acceptable, personally I use master. This variable contains the main window that everything else is placed into. You also hadn't put Tk() into any variable, meaning that when you hit root.mainloop() there was nothing to enter the main loop, this was because you were trying to declare root = Tk() inside gameMenu, which wasn't getting called in your program.
If you want to open windows within tkinter it's probably easier to write something like this:
from tkinter import *
master = Tk() #Declaring of main window
def ProceedButtonCommand(mainframe, master): #Command to attach to proceed button
mainframe.destroy()
DrawSecondScreen(master) #This line is what lets the command tied to the button call up the second screen
def QuitButtonCommand(master):
master.destroy()
def DrawFirstScreen(master):
mainframe = Frame(master) #This is a way to semi-cheat when drawing new screens, destroying a frame below master frame clears everything from the screen without having to redraw the window, giving the illusion of one seamless transition
ProceedButton = Button(mainframe, text="Proceed", command=lambda: ProceedButtonCommand(mainframe, master)) #Lambda just allows you to pass variables with the command
QuitButton = Button(mainframe, text = "Quit", command=lambda: QuitButtonCommand(master))
mainframe.pack()
ProceedButton.pack()
QuitButton.pack()
def DrawSecondScreen(master):
mainframe = Frame(master)
Label1 = Label(mainframe, text="Temp")
mainframe.pack()
Label1.pack()
DrawFirstScreen(master)
master.mainloop() #The mainloop handles all the events that occur in a tkinter window, from button pressing to the commands that a button runs, very important
This little script just draws a screen with two buttons, one draws a new screen with the text "temp" on it and the other button closes the master window.
In the future it's probably a better idea to ask a friend who is experienced in programming to help with this kind of stuff. Get talking on some computing forums, I'm sure you'll find a group of sharing and fixing code quickly.

Categories