#Last one Looses (II)
from tkinter import *
from tkinter import ttk
root = Tk()
#window
root.title("Last one Looses Mark II")
#Counters Entry
counters = StringVar()
countersL = Label(root, text = "How many counters do you want to play with (10-50)")
countersL.pack(side = LEFT)
countersE = Entry(root, textvariable = counters, bd = 5)
countersE.pack(side = RIGHT)
#Function to process this
def countersinput():
no_counters = int(input(counters.get()))
no_counters = int(input(counters.get()))
#Submit Button
countersB = Button(root, text = "Submit", command = countersinput)
countersB.pack(side = BOTTOM)
#Making sure the counters are between 10-50
while no_counters > 50 or no_counters < 10:
Error = Message(root, text="You need to pick between 10 and 50 counters...")
Error.pack()
counters = StringVar()
countersL = Label(root, text = "How many counters do you want to play with (10-50)")
countersL.pack(side = LEFT)
countersE = Entry(root, textvariable = counters, bd = 5)
countersE.pack(side = RIGHT)
def countersinput():
no_counters = int(input(counters.get()))
countersB = Button(root, text = "Submit", command = countersinput)
countersB.pack(side = BOTTOM)
#Sucess Message
Sucess = Message(root, text=("You are playing with",no_counters,"counters"))
root.mainloop()
Whenever I run it in IDLE the tkinter window does not come up and when I run it into the command line (python one...) it displays the window but with no "submit" button.
I'm really confused please help!
First off, do you realize that your GUI program is asking for input from the command line, and that you're doing that before creating the submit button? That's the reason why the submit button is not showing up. If you're writing a GUI program, you should not be trying to read input from the command line.
If you enter a number between 10 and 50 from the terminal, your code should display a window. However, if you enter a number outside that range, nothing will ever show because of the while no_counters ... loop. That loop will run infinitely, preventing any other interaction with the GUI, and preventing any other widgets from showing up.
Related
So I'm working on a function does something (turns a motor) every second. For counting the second I use time.sleep(1) because I don't know any other way to wait.
def wash_loop(wash_time):
count = 0
dist = 0
global error_flag
error_flag = 0
while (count < wash_time):
if(count%2==0):#going forward
GPIO.output(Motor_IN1,GPIO.HIGH)
GPIO.output(Motor_IN2,GPIO.LOW)
GPIO.output(Motor_EN,GPIO.HIGH)
print(count)
time.sleep(MOTOR_SLEEP)
else:#going backwards
GPIO.output(Motor_IN1,GPIO.LOW)
GPIO.output(Motor_IN2,GPIO.HIGH)
GPIO.output(Motor_EN,GPIO.HIGH)
print(wash_time - count) #want to display this on a Tkinter window instead
time.sleep(MOTOR_SLEEP)
count+=1
dist = distance_check()
if(dist < CRITICAL_DIS):
error_alert()
break
if(count>=wash_time):
GPIO.output(Motor_EN, GPIO.LOW)
break
The Tkinter function that I'm trying to do this in looks like this:
def wash_window():
#create the main window for GUI control applcation
window2 = TK.Tk()
temp = TK.IntVar()
window2.geometry(WINDOW_GEOMETRY)
window2.title("Wash Cycle ")
#create the frame that will hold instructions
frame0 = TK.Frame(window2)
frame0.pack(side=TK.TOP)
TK.Label(frame0, text="You've selected custom wash cycle").grid(row=0,column=0)
TK.Label(frame0, text="Please select the water temperature for the wash.")\
.grid(row=1,column=0)
frame1 = TK.Frame(window2)
frame1.pack(side=TK.TOP)
temp.get()
hot_button = TK.Radiobutton(frame1, text="HOT", variable=temp, value=1 ).grid(row=0, column=0)
cold_button = TK.Radiobutton(frame1, text="COLD", variable=temp, value=2).grid(row=0,column=1)
warm_button = TK.Radiobutton(frame1, text="WARM", variable=temp, value=3).grid(row=0,column=2)
#create the frame that will hold control entry in the window
frame2 = TK.Frame(window2)
frame2.pack(side=TK.TOP)
TK.Label(frame2, text = "Please enter the time below for the wash cycle").grid(row=0,column=0)
user_entry = TK.Entry(frame2)
user_entry.grid(row=1,column=0)
frame3= TK.Frame(window2)
frame3.pack(side=TK.TOP)
start_button = TK.Button(frame3, text="START", command = lambda: wash_cycle(user_entry,temp)).grid(row=0, column=0)
# stop_button = TK.Button(frame3, text="STOP", command = lambda: wash_cycle(user_entry,temp)).grid(row=0, column=1)
quit_button = TK.Button(frame3, text="QUIT", command = window2.destroy).grid(row=0, column=2)
What I'm trying to do is display the countdown (from the entered time to 0) on this Tkinter window as soon as the person presses start in the window. This is different from using the after() function because I want to show a value from a function which is only executing once, only with the exception that it has a loop.
Thank You!
So what you could do is work with threading.
You Need to:
from threading Import Timer
Then you create a timer
your_timer = Timer(the_seconds_you_want_to_wait, the_function_to_call)
You are calling a function with this and in that function you can display anything in your tkinter window.
What I recommend you to do here is create a Label and then change the properties of it.
For example if you want to show a number on a label:
L1 = Label(root, text="your text here")
L1.pack()
Now if you want to edit that later:
L1.configure(text="your new text here")
your_timer.start()
And at the end of your function you Need to Start the timer in order to the create a cycle or just create a Loop for it.
Basically, I want to go through answers and check every time if that's correct with a button and then pop it from the list. In another file/code/application it's working when I try to use it on my Gui Application it doesn't iterate and only keeps the first answer right.
I tried multiple things like using Dictionaries and getting the key but it still doesn't iterate over after the Button press.
This is the code that works fine:
while answers == True:
answers = ["Sayajin", "Namek", "Cell", "TournamentOfPower"]
for a in range(4):
s = input()
if s in answers[0]:
print("Richtig")
answers.pop(0)
This is the code that doesnt work:
def check(event):
answers = ["Sayajin", "Namek", "Cell", "TournamentOfPower"]
for a in range(4):
s = entrysaga.get()
if s in answers[0]:
print("Richtig")
answers.pop(0)
Complete Code:
from tkinter import *
import tkinter.messagebox
import time
import random
root = Tk()
#Hint Button
hint = Button(root, text= "Hint")
hint.bind("<Button-1>")
hint.place(x=50, y=20)
#How to Play Button + Info Message how to play
def Howtoplay():
tkinter.messagebox.showinfo("How to play", "To start the game u have
to press the button (Start)\n---------------------------------------------
----------------\n"
""
"Then the Picture will switch
and its going to show u a Character and u have to guess from which Dragon
Ball Saga he is.\n--------------------------------------------------------
-----\n"
"Just type it in the Entry and
press Check after that if u were right the next picture shows up")
info = Button(root, text="How to Play", command=Howtoplay)
info.bind("<Button-1>")
info.place(x=150, y=20)
#textwidget
textwidget = Label(root, text="Entry the DragonBall Saga:")
#entry widget
entrysaga = Entry(root)
#Pictures for guessing the Saga
Sayajin = PhotoImage(file="sayajinsaga.png")
Namek = PhotoImage(file="NamekSaga.png")
Cell = PhotoImage(file="CellSaga.png")
Buu = PhotoImage(file="BuuSaga.png")
TournamentOfPower = PhotoImage(file="TournamentOfPowersaga.png")
#Start function
def start():
labelSagas.config(image=Sayajin)
#define check for pictures
def check(event):
answers = ["Sayajin", "Namek", "Cell", "TournamentOfPower"]
for a in range(4):
s = entrysaga.get()
if s in answers[0]:
print("Richtig")
answers.pop(0)
#button check
buttonsaga = Button(root, text="Check")
buttonsaga.bind("<Button-1>", check)
textwidget.place(x=300, y=170)
entrysaga.place(x=300, y= 200)
buttonsaga.place(x=440, y=195)
#Start Button
start = Button(root, text="Start", command=start)
start.bind("<Button-1")
start.place(x=400, y=20)
# Label with start picture,
startpic = PhotoImage(file="dbzsagas.png")
labelSagas = Label(root, image=startpic)
labelSagas.place(x=25, y=80)
#size of window
root.geometry("500x280")
#window title
root.title("Dragon Ball Saga´s guessing game")
#start of the window
root.mainloop()
My excepted output should be like in the first code that it iterates over and after getting the first answer right ur on to the next one. But the actual result it that stays on the first.
I have moved the widgets which should appear when you press the Start button. They are all in the def start(): function as they would not appear otherwise.
As entrysaga was being called within a different function it could not find the inputted value as the variable is not a global variable. By using global entrysaga it means that it is and can be called from anywhere within the script.
This is how it looks:
from tkinter import *
import tkinter.messagebox
import time
import random
root = Tk()
#Hint Button
hint = Button(root, text= "Hint")
hint.bind("<Button-1>")
hint.place(x=50, y=20)
#How to Play Button + Info Message how to play
def Howtoplay():
tkinter.messagebox.showinfo("How to play", "To start the game u have to press the button (Start)\n--------------------------------------------- ----------------\n"
""
"Then the Picture will switch and its going to show u a Character and u have to guess from which Dragon Ball Saga he is.\n-------------------------------------------------------- -----\n"
"Just type it in the Entry and press Check after that if u were right the next picture shows up")
info = Button(root, text="How to Play", command=Howtoplay)
info.bind("<Button-1>")
info.place(x=150, y=20)
#Pictures for guessing the Saga
Sayajin = PhotoImage(file="sayajinsaga.png")
Namek = PhotoImage(file="NamekSaga.png")
Cell = PhotoImage(file="CellSaga.png")
Buu = PhotoImage(file="BuuSaga.png")
TournamentOfPower = PhotoImage(file="TournamentOfPowersaga.png")
#Start function
def start():
labelSagas.config(image=Sayajin)
global entrysaga
entrysaga = tkinter.Entry(root)
entrysaga.place(x=300, y= 200)
buttonsaga = Button(root, text="Check")
buttonsaga.bind("<Button-1>", check)
buttonsaga.place(x=440, y=195)
textwidget = Label(root, text="Entry the DragonBall Saga:")
textwidget.place(x=300, y=170)
#define check for pictures
def check(event):
answers = ["Sayajin", "Namek", "Cell", "TournamentOfPower"]
for a in range(4):
s = entrysaga.get()
if s in answers[0]:
print("Richtig")
answers.pop(0)
#Start Button
start = Button(root, text="Start", command=start)
start.bind("<Button-1")
start.place(x=400, y=20)
# Label with start picture,
startpic = PhotoImage(file="dbzsagas.png")
labelSagas = Label(root, image=startpic)
labelSagas.place(x=25, y=80)
#size of window
root.geometry("500x280")
#window title
root.title("Dragon Ball Saga´s guessing game")
#start of the window
root.mainloop()
Hope this helps! :)
So I'm attempting to make a program with tkinter, and so far, things have gone somewhat as hoped, and I nearly achieved what I wanted.
But I've got a problem with destroying labels.
from tkinter import *
root = Tk()
root.geometry("500x500")
def controleerAntwoord(gekozenHeld, submit, eersteHintButton):
antwoord = entry.get()
if antwoord == gekozenHeld:
submit.destroy()
eersteHintButton.destroy()
eersteHint("destroy", button)
startspel()
def eersteHint(superheldHint, button):
hintTextLabel = Label(root, text = "First hint: ")
hintLabel = Label(root, text = superheldHint)
if superheldHint != "destroy":
hintTextLabel.pack()
hintLabel.pack()
button.destroy()
if superheldHint == "destroy":
hintTextLabel.destroy()
hintLabel.destroy()
def startspel():
entry.delete(0, 'end')
gekozenHeld = "test"
superheldHint1 = 'hey'
eersteHintButton = Button(root, text = "Give First Hint", command = lambda: eersteHint(superheldHint1, eersteHintButton))
submit = Button(root, text = "Submit Answer",foreground = "blue", command = lambda: controleerAntwoord(gekozenHeld, submit, eersteHintButton))
eersteHintButton.pack(side = BOTTOM)
entry.pack(side = BOTTOM)
submit.pack(side = BOTTOM, pady = 20)
def start_up():
name = entry.get().strip()
if name != "":
button.destroy()
giveName.destroy()
startspel()
giveName = Label(root, text="Insert your name: ")
entry = Entry(root)
button = Button(root, text="Enter", command=start_up)
entry.pack()
button.pack()
root.mainloop()
This is my current code so far, I know it looks big, but a lot of it can be ignored for this question.
As to how the program works, you enter your name and get taken to the next window.
There you can press the submit button and enter some text, as well as asking for a hint.
When you press the hint button, you get some text on the screen, and when you submit the correct answer, which in this case, is "test", the text should disappear. But it does not.
Any ideas on what I'm doing wrong?
The problem is that you're using a local variable, but expecting that local variable to somehow be remembered the second time you call the function. All your code does is create a label and then immediately destroy the one it just created. If you want it to destroy the one created earlier, you'll have to store that in a global variable.
I just want that when I type my name inside the entry box then appears in another entry with some add text. The idea is type in the entry below and after that it showed in the big entry.I was looking for this solution, but just found place in Label. I don't want in Label. The window is more big, must drag to show the entry. There's is a picture that i use in this script:
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
cat = Entry(root)
cat.place(x=48, y=25, width= 350, height=140)
user = Entry(root)
user.place(x=75, y=550)
btn = Button(root, text='START')
btn.place(x=220, y=410)
root.mainloop()
#
Ok, It works the way you told me,thank you!
But now i'm facing another problem.
The problem is when i insert the function of the game in the second window. I tested in one window and it works, but when i place the function in the second window gives an error when i press the "Start" button:
'''user_try = int(txt.get())
NameError: name 'txt' is not defined'''
When i press reset button gives another error:
'''user_try = int(txt.get())
NameError: name 'txt' is not defined'''
So i know that is missing definition, but i don't know how to make a reference for this command that it's in the second window. Like i said running with just one window the program works.
Maybe i should make using class, i don't know, but i wish to make this way that i started. However if there's no other way to do as i'm doing, let's go.
I just simplify the script here, actualy the main script is more bigger, so my idea is when open the program, there is a window and the user read the instructions about the game and proceed open the second window. The window have pictures and some hidden buttons in the next picture, so there will be an interactivity with the environment.
The guess number is just the beggining. After that there will be new challeges.
I'm very excited doing this, but i'm stuck in this point. The part one i finished, the pictures, the hidden buttons it's exacly the way i want, but the challenge stops here in this problem.
from tkinter import *
from PIL import Image, ImageTk, ImageSequence
import random
from tkinter import messagebox
pc = random.randint(1,10)
def reset():
global pc
pc = random.randint(1,10)
cat['text'] = 'Ok! Lets Try Again!'
def openwin2():
win1.withdraw()
win2 = Toplevel()
win2.geometry('350x300+180+100')
win2.title('second window')
txt = Entry(win2)
txt.place(x=10,y=10)
cat = Label(win2,wraplength=300)
cat.place(x=10,y=50)
cat.config(text='Hi! I Am thinking a number between 1 and 10.')
btn = Button(win2,text='start',command=check)
btn.place(x=30, y=150)
btn2 = Button(win2, text='reset', command=reset)
btn2.place(x=110,y=150)
win2.mainloop()
def check():
user_try = int(txt.get())
if user_try < pc:
msg = 'Hmmmm... the number, which I thought of, is greater than this.'
elif user_try > pc:
msg = 'How about trying a smaller number ?!'
elif user_try == pc:
msg = 'Well Done! You guessed! It was %s the number!' % user_try
else:
msg = 'Something Went Wrong...'
cat['text'] = msg
win1 = Tk()
win1.title('First Window')
win1.geometry('350x300')
user = Label(win1,text='first window')
user.place(x=10,y=10)
btn1 = Button(win1,text='Open Window 2', command=openwin2)
btn1.place(x=10,y=50)
win1.mainloop()
There are multiple ways to do this in tkinter, here's a rework of your code using StringVar objects set to the textvariable properties of your Entry objects:
import tkinter as tk
def doit():
out_string.set("Hello " + in_string.get())
root = tk.Tk()
in_string = tk.StringVar()
out_string = tk.StringVar()
cat = tk.Entry(root, textvariable=in_string)
cat.place(x=20, y=25, width=100)
user = tk.Entry(root, textvariable=out_string)
user.place(x=20, y=75)
btn = tk.Button(root, text='START', command=doit)
btn.place(x=20, y=150)
root.mainloop()
Per #Mike-SMT, here's a different approach using Entry.get() and Entry.insert(). It augments the text when the user clicks the button:
import tkinter as tk
def doit():
user.insert(tk.END, cat.get())
root = tk.Tk()
cat = tk.Entry(root)
cat.place(x=20, y=25, width=100)
user = tk.Entry(root)
user.place(x=20, y=75)
user.insert(0, "Hello ")
btn = tk.Button(root, text='START', command=doit)
btn.place(x=20, y=150)
root.mainloop()
However, you'll see that subsequent button clicks keep appending the text. When working with Entry.insert(), you need to work with Entry.delete() and/or other Entry methods to properly manipulate the text.
I want to create a password entry.
One easy solution is:
password = Entry(root, font="Verdana 22")
password.config(show="*");
but the problem is that to avoid typos, I want to show the item clicked to be visible only for a few seconds, while everything else is hidden. After a few seconds everything is hidden.
It's not easy to do exactly what you want with Tkinter, but here's something close: when you press a key it displays the whole contents of the Entry, but after one second the text is hidden again.
I developed this on Python 2; to use it on Python 3 change Tkinter to tkinter.
import Tkinter as tk
class PasswordTest(object):
''' Password Entry Demo '''
def __init__(self):
root = tk.Tk()
root.title("Password Entry Demo")
self.entry = e = tk.Entry(root)
e.pack()
e.bind("<Key>", self.entry_cb)
b = tk.Button(root, text="show", command=self.button_cb)
b.pack()
root.mainloop()
def entry_cb(self, event):
#print(`event.char`, event.keycode, event.keysym )
self.entry.config(show='')
#Hide text after 1000 milliseconds
self.entry.after(1000, lambda: self.entry.config(show='*'))
def button_cb(self):
print('Contents:', repr(self.entry.get()))
PasswordTest()
It would be tricky to only display the last char entered. You'd have to modify the displayed string manually while maintaining the real password string in a separate variable and that's a bit fiddly because the user can move the insertion point cursor at any time.
On a final note, I really don't recommend doing anything like this. Keep passwords hidden at all times! If you want to reduce the chance of typos in newly-chosen passwords, the usual practice is to make the user enter the password twice.
This a simple trick to visible the password with a checkbutton.
When it is checked the password will be visible
from Tkinter import *
from tkinter import ttk
def show_hide_psd():
if(check_var.get()):
entry_psw.config(show="")
else:
entry_psw.config(show="*")
window = Tk()
window.wm_title("Password")
window.geometry("300x100+30+30")
window.resizable(0,0)
entry_psw = Entry(window, width=30, show="*", bd=3)
entry_psw.place(x = 5, y = 25)
check_var = IntVar()
check_show_psw = Checkbutton(window, text = "Show", variable = check_var, \
onvalue = 1, offvalue = 0, height=2, \
width = 5, command = show_hide_psd)
check_show_psw.place(x = 5, y = 50)
window.mainloop()