GUI not running properly - python

I am using mac OS X python. I'm working with GUI right now and is making a simple window with three buttons. I'm trying to configure some buttons to make them do something but it is not working. Can anyone tell me what the problem is? So far I have a little window with three buttons. I wrote the code:
win=Tk()
f=Frame(win)
b1=Button(f,text="one")
b2=Button(f,text"two")
f.pack()
def but1() : print "Button one was pushed"
b1.configure(command=but1)
I am getting the error message invalid syntax for that.

Your program needs to call root.mainloop() on the last line. You also have the problem that you aren't calling pack or grid on the buttons. After adding the call to mainloop() you'll just see any empty window until you call pack or grid on the buttons.

The only thing that I see wrong with your code is that you forgot to include = when you define b2. Running exactly what you have written will raise a Syntax Error.
from Tkinter import *
win = Tk()
f = Frame(win)
b1 = Button(f, text="one")
b2 = Button(f, text="two") # Don't forget the equals sign.
f.pack()
def but1():
print "Button one was pushed"
b1.configure(command=but1)

Related

Create a function that ends mainloop and starts new one in tkinter

I'm writing my first GUI program today using Tkinter and I have stumbled onto a problem. I am trying to make a game that starts with an introduction window that closes after you press a button, then opens a new window where you can choose one of two modes. Unfortunately, I just can't get it running. It looks a little something like this.
#These are the functions that I defined to make it work
def start():
root.destroy()
def Rules_mode_1():
root.destroy
rules1 = Tk()
understood1 = Button(rules1, text="I understood", command="Start_game_mode_1")
understood.pack()
rules1.mainloop
# I haven't added rules 2 yet cause I couldn't get it to work with rules 1 so I haven't even #bothered but it would be the same code just switching the 1 for a 2. But really it isn't even
#necessary to have 2 different rule functions because the rules are the same but I couldn't think
#of another way to go about it. if you have an idea let me know
def Start_game_mode_1():
rules1.destroy #<----- THIS IS WHERE THE PROBLEM LIES. JUST DOESN'T RUN
gamemode1 = Tk()
#Here I would have the game
gamemode1.mainloop()
#now same here don't have gamemode 2 yet cause it just doesn't work yet
#This is where it really starts
root = Tk()
startbutton = Button(root, text="Start", command=start)
startbutton.pack
root.mainloop
root = Tk()
def mode():
mode1 = Button(root, command=Rules_mode_1)
mode1.pack
mode2 = #Buttonblablabla
mode()
root.mainloop()
Now I've been trying around for hours, trying to give the mainloops different names. For example giving the
rules1.mainloop
#the name
root.mainloop
but that obviously didn't work. I tried it with dozens of helper function and with the lambda expression and did hours of research but just can't seem to fix it. Does anybody have any ideas? Please be respectful and keep in mind it's my first time using Tkinter.
Thank you for your help!
After the comments didn't really help me I just tried things out for hours and in case anybody ever is having a a similar problem and reads this: The rules1 variable is inside a function, and therefore only local, which means it can't be destroyed in another function. I fixed it by making it a global, like:
def Rules_mode_1():
root.destroy
global rules1
rules1 = Tk()
understood1 = Button(rules1, text="I understood", command="Start_game_mode_1")
understood.pack()
rules1.mainloop
After that I could destroy the mainloop in the next function.

using Tkinter with condition in python

I want to use Tkinter in loop and not sure how to do that. I want to display an "Correct" message when certain condition is met using Tkinter. for ex if the value is <=20 then it should display message otherwise show " not correct". I am only able to create a code to display message but do not know how to use this message with the condition. Below is my code :
import tkinter
from tkinter import messagebox
# This code is to hide the main tkinter window
root = tkinter.Tk()
root.withdraw()
# Message Box
messagebox.showinfo(" Correct!!")
My solution will going to have an example inspired by your explanation about what you are trying to do.
Well your code would not do anything like you want to. So I am writing a code which will take a number input from a user. If the number is greater than 20 then it would display "Correct" else it would display "Incorrect".
Here is the code I wrote:
import tkinter
from tkinter import messagebox
root = tkinter.Tk()
question = tkinter.Label(root, text="Enter any number")
question.place(x=5, y=5)
question_entry = tkinter.Entry(root)
question_entry.place(x=5, y=50)
def check():
x = 20
y = int(question_entry.get())
if y >= x:
messagebox.showinfo(title="Check", message="Correct!")
elif y < x:
messagebox.showinfo(title="Check", message="Incorrect!")
else:
messagebox.showerror(title="Check", message="Some unexpected error occured!")
submit_button = tkinter.Button(root, text="Start", command=check)
submit_button.place(x=5, y=100)
root.mainloop()
Explanation:
Using label to display "Enter any number"
I have used Entry widget to take input from the user. And to retrieve it I have used int(question_entry.get()). Also I have added int() to make the entry an integer as the default entry is str.
The function check is created so as to run the program when the button is pressed. I have used command=check attribute run the program when it is clicked.
showinfo is being used to send a message in a separate window. showerror is created in else condition just in case some error comes up. (less likely to happen)
I have removed the root.withdraw() statement as this program can be used multiple time. But just in case if you want to hide the window you can add root.withdraw() just above the line x=20 and it would work just fine. (I tried is already)
It there is still something that I failed to explain, please feel free to ask in the comments. :)

With two tkinter windows, script does not execute after one's mainloop

I have a script which has two tkinter.Tk() objects, two windows. One is hidden from the start (using .withdraw()), and each has a button which hides itself and shows the other (using .deiconify()). I use .mainloop() on the one shown in the beginning. Everything works, but when I close either window, the code after the mainloop() doesn't run, and the script doesn't end.
I suppose this is because one window is still open. If that is the case, how do I close it? Is it possible to have a check somewhere which closes a window if the other is closed?
If not, how do I fix this?
The essence of my code:
from tkinter import *
window1 = Tk()
window2 = Tk()
window2.withdraw()
def function1():
window1.withdraw()
window2.deiconify()
def function2():
window2.withdraw()
window1.deiconify()
button1 = Button(master=window1, text='1', command=function1)
button2 = Button(master=window2, text='2', command=function2)
button1.pack()
button2.pack()
window1.mainloop()
Compiling answers from comments:
Use Toplevel instead of multiple Tk()s. That's the recommended practice, because it decreases such problems and is a much better choice in a lot of situations.
Using a protocol handler, associate the closing of one window with the closing of both. One way to do this is the following code:
from _tkinter import TclError
def close_both():
for x in (window1,window2):
try:
x.destroy()
except TclError:
pass
for x in (window1,window2):
x.protocol("WM_DELETE_WINDOW", close_both)

Tkinter Entry returns float values regardless of input

I have some pretty simple code right now that I am having issues with.
root = Tk()
label1 = Label(root, text ="Enter String:")
userInputString = Entry(root)
label1.pack()
userInputString.pack()
submit = Button(root,text = "Submit", command = root.destroy)
submit.pack(side =BOTTOM)
root.mainloop()
print(userInputString)
When I run the code everything operates as I would expect except
print(userInputString)
for an input asdf in the Entry print will return something like 0.9355325
But it will never be the same value back to back always random.
I am using python 3.5 and Eclipse Neon on a Windows 7 Machine.
Ultimately the goal is to accept a string from the user in the box that pops up and then be able to use that value as string later on. For example, it might be a file path that needs to be modified or opened.
Is Entry not the correct widget I should be using for this? Is there something inherently wrong with the code here? I am new to python and don't have a lot of strong programming experience so I am not even certain that this is set up right to receive a string.
Thanks in advance if anyone has any ideas.
There are two things wrong with your print statement. First, you print the widget, not the text in the widget. print(widget) prints str(widget), which is the tk pathname of the widget. The '.' represents the root window. The integer that follows is a number that tkinter assigned as the name of the widget. In current 3.6, it would instead be 'entry', so you would see ".entry".
Second, you try to print the widget text after you destroy the widget. After root.destroy, the python tkinter wrapper still exists, but the tk widget that it wrapped is gone. The following works on 3.6, Win10.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Enter String:")
entry = tk.Entry(root)
def print_entry(event=None):
print(entry.get())
entry.bind('<Key-Return>', print_entry)
entry.focus_set()
submit = tk.Button(root, text="Submit", command=print_entry)
label.pack()
entry.pack()
submit.pack()
root.mainloop()
Bonus 1: I set the focus to the entry box so one can start typing without tabbing to the box or clicking on it.
Bonus 2: I bound the key to the submit function so one can submit without using the mouse. Note that the command then requires an 'event' parameter, but it must default to None to use it with the button.
The NMT Reference, which I use constantly, is fairly complete and mostly correct.

lift a tkMessageBox

I am using tkMessageBox.showinfo (info at tutorialspoint) to popup warnings in my program.
The problem happens only when the warning is called with a second TopLevel window (apart from the main one) on screen: in this case the warning remains hidden behind the second TL window.
I tried to call it thus:
tkMessageBox.showinfo(title='Warning',message=s).lift()
but it doesnt work. Any ideas?
I think the message box is only ever guaranteed to be above its parent. If you create a second toplevel and you want a messagebox to be on top of that second window, make that second window the parent of the messagebox.
tl2 = tk.Toplevel(...)
...
tkMessageBox.showinfo("Say Hello", "Hello World", parent=tl2)
I do not see the issue that you describe. The code I wrote below is just about the minimum needed to create a window which creates a second window. The second window creates an info box using the showinfo method. I wonder whether you have something besides this. (Note that I made the windows somewhat large in order to attempt cover up the info window.)
from Tkinter import Tk, Button, Toplevel
import tkMessageBox
top = Tk()
def make_window():
t = Toplevel(top)
t.title("I'm Window 2. Look at me too!")
B2 = Button(t, text = "Click me", command = hello)
B2.pack()
t.geometry('500x500+50+50')
def hello():
tkMessageBox.showinfo("Say Hello", "Hello World")
B1 = Button(top, text = "New Window", command = make_window)
B1.pack()
top.title("I'm Window 1. Look at me!")
top.geometry('500x500+100+100')
top.mainloop()
This was tested on Windows 7 (64-bit) using Python 2.7 (32-bit). It produces something like this:

Categories

Resources