Can someone answer why this Tkinter doesn't work? - python

I'M SO CONFUSED
Keep in mind that I'm a beginner at programming/python so if my code is unorganized or badly worded, ignore it, I'm getting better lol
I'm just playing with tkinter and I'm trying to get a login screen that has a checkbox that toggles the visibility of the password. I just don't understand anymore. The "show" argument won't change based on the variable it was assigned and I don't know why.
showPassword = IntVar()
show = None
def apply():
print(showPassword.get())
sspass = showPassword.get()
print(type(sspass))
if sspass == 1:
show = None
elif sspass == 0:
show = "*"
spB = Checkbutton(root, text="Toggle Show Password", variable=showPassword).grid(row=10, column=1)
applyButton = Button(root, text="Apply", command=apply).grid(column=1, row=5)
Password = entry(root, show=show)

I have arranged a snippet of code (that is not perfect for you to follow but...) based on yours that at least works for you to progress. Your code is incomplete I suppose, it has also some errors. You have to configure the show parameter in the widget. Changing your show var won't do anything to the widget.
You'll have to use the form widget['show'] = somevalue. Or the .configurewidget method. For both you'll need a widget reference. If you grid a widget in the same line you create it, grid will return nothing so you loose it. Break that in two steps and keep the reference for the widget at creation (first step). entry is actually called Entry. These where the most prominet errors I saw.
from tkinter import Button, Checkbutton, Entry, Tk, IntVar
root = Tk()
showPassword = IntVar()
show = None
def apply():
print(showPassword.get())
sspass = showPassword.get()
print(type(sspass))
if sspass == 1:
Password['show'] = ""
elif sspass == 0:
Password['show'] = "*"
Password.update()
spB = Checkbutton(root, text="Show Password", variable=showPassword).grid(row=10, column=1)
applyButton = Button(root, text="Apply", command=apply).grid(column=1, row=5)
Password = Entry(root, show=show)
Password.grid(row=3, column=1)
root.mainloop()

Related

Tkinter how to lock Text widget by checking checkbox?

I am new to programming and Tkinter. I want to DISABLED textbox when checkbox is pressed and open it NORMAL when box is not ticked. Here is my code:
from tkinter import *
root = Tk()
def lock_fields():
if check == True:
data.configure(state=DISABLED)
if check == False:
data.configure(state=NORMAL)
check = BooleanVar()
open_for_edit = Checkbutton(root, text="check the box for editing", variable=check,
onvalue=True, offvalue=False, command=lambda: lock_fields())
open_for_edit.pack()
check = check.get()
data = Text(root)
data.insert(END, "I would like to be able to edit this text only when checkbox is checked.")
data.pack()
root.mainloop()
It seems that for some reason the check-variable is always False when it enters to lock_fields function. I tried passing check argument to the method.
You're pretty close, only thing is that the check.get() line must be in the function. Also you don't need the lambda. Try this:
from tkinter import *
root = Tk()
def lock_fields():
if check.get():
data.configure(state=DISABLED)
else:
data.configure(state=NORMAL)
check = BooleanVar()
open_for_edit = Checkbutton(root, text="check the box for editing", variable=check, onvalue=True, offvalue=False, command=lock_fields)
open_for_edit.pack()
data = Text(root)
data.insert(END, "I would like to be able to edit this text only when checkbox is checked.")
data.pack()
root.mainloop()

Clearing a entry containing both a 'Integer' and 'String'

I'm trying to clear a Tkinter Entry Box by using a Tkinter Button. The problem is that my entry includes both 'Integers' aswell as a 'String' and my code wont clear the entry.
I have tried changing the attributes of the clearing method. Right now it's .delete(0, END). But i have tried changing it to .delete("0.0", END) and .delete(0.0, END. But this is just me desperatly trying things out.
enter code here
from tkinter import *
root = Tk()
def validatecontent(entry_text1):
return (entry_text1.isdigit() == bool(entry_text1)) or entry_text1 ==
(".")
def clear_entry():
entry_1.delete(0, END)
vcmd = (root.register(validatecontent), '%S')
entry_text1 = StringVar()
entry_1 = Entry(root, width=11, textvariable=entry_text1,
validate='all', validatecommand=vcmd)
entry_1.pack()
button = Button(root, width=10, text="Clear",
command=clear_entry)
button.pack()
root.mainloop()
If the entry contains Integers alone it gets cleared. But if the entry contains '.' nothing happens, no error code at all.

Python Tkinter label not destroying

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.

Radio button values in Python Tkinter

I am trying to create a dialog box in Python using Tkinter. The goal is to have a dialog box with two radio buttons and an "OK" button. Radio button one selects the option "default". Radio button two selects the option "user defined." The "OK" button closes the window.
Question 1: How do I save the value from the radio button? That is, how do I pass the selected radio button to the rest of my script?
Question 2: How can I have the second radio button include user text input (along the lines of tkSimpleDialog.askstring)? I would like that button to show a radiobutton, a prompt ("Enter value:"), and a space for the user to enter text -- all on one line as a single radiobutton option.
So the whole dialog should have the top radio button be a normal radio button, and the second button specify user input and include a space for that user input (and the OK button).
So far I have a dialog open with two options, but the value doesn't get passed to anything I can see; selection is returned as 0 even before I select a radiobutton.
Any help on either question would be greatly appreciated, thank you.
Here's my script so far:
from Tkinter import*
master = Tk()
var = IntVar()
Label(master, text = "Select OCR language").grid(row=0, sticky=W)
Radiobutton(master, text = "default", variable = var, value = 1).grid(row=1, sticky=W)
Radiobutton(master, text = "user-defined", variable = var, value = 2).grid(row=2, sticky=W)
Button(master, text = "OK", command = master.quit).grid(row=3, sticky=W)
selection = var.get()
print "Selection:", selection
mainloop()
#If selection == 0 do one thing
#If selection == 1 do something else...
A bit late to the party, but I stumbled upon this question while trying to find something on Tkinter radiobuttons.
Question 1:
I changed three things:
1) I immediately set the value of var to 1 after you've defined it. This is done by doing var.set(1) and will make sure your first radio button is selected (which has a value of 1, as you defined it later on in the code).
2) I've replaced your master.quit command with a function called quit_loop. In this function:
The var value is printed through a print and get statement. The get will 'get' the current value of var, which depends on which radio button is selected.
I create a global variable within this function, which will then get the current value of var.
I added parentheses to master.quit() because this is no longer in the command of a radio button. Note that if you plan on using IDLE, master.destroy() might be a more suitable alternative.
3) Due to the creation of the selection variable in the function we now have your wanted value stored in a variable. There is one final if-statement at the end of the code to show it's working.
from Tkinter import *
master = Tk()
var = IntVar()
var.set(1)
def quit_loop():
print "Selection:",var.get()
global selection
selection = var.get()
master.quit()
Label(master, text = "Select OCR language").grid(row=0, sticky=W)
Radiobutton(master, text = "default", variable=var, value = 1).grid(row=1, sticky=W)
Radiobutton(master, text = "user-defined", variable=var, value = 2).grid(row=2, sticky=W)
Button(master, text = "OK", command=quit_loop).grid(row=3, sticky=W)
master.mainloop()
if selection == 1:
print "My Value is equal to one."
elif selection == 2:
print "My value is equal to two."
Question 2:
I would keep it simple and just add a label and an entry box right after your radio button. This means that we also have to work with columns as you didn't have any defined in your previous code, which makes everything default to column 0. We want your second radio button to be 'radio, label, entry' which takes three columns.
1) The previous label containing "Select OCR language" will be spanned over three columns with columnspan=3 added to the grid arguments. The same goes for your first radio button.
2) I added a Label and an Entry after your second radio button. Note that the columns go from 0 to 2, defining our three columns. The label has a simple "Enter value:" text, whereas the entry has the variable textvariable=entry_text. I added this variable entry_text to the beginning of your code and immediately set its value to ###. Note that this is a string (hence, textvariable) so adding checks for integer numbers only is up to you.
3) Of course, this is not linked to the second radio button. It still has a value of 2 if we select it, not the value of the Entry widget. That's why, in the previously created quit_loop function, I added a small if statement that assigns the value of the entry to selection if the second radio button was selected.
from Tkinter import *
master = Tk()
var = IntVar()
var.set(1)
entry_text = StringVar()
entry_text.set("###")
def quit_loop():
print "Selection:",var.get()
global selection
selection = var.get()
if selection == 2:
selection = entry_text.get()
master.quit()
# Add columnspan to these widgets
Label(master, text = "Select OCR language").grid(row=0, sticky=W, columnspan=3)
Radiobutton(master, text = "default", variable=var, value = 1).grid(row=1, sticky=W, columnspan=3)
# Order these widgets in their appropriate columns
Radiobutton(master, variable=var, value = 2).grid(row=2, sticky=W, column=0)
Label(master, text="Enter value:").grid(row=2, sticky=W, column=1)
Entry(master, textvariable=entry_text).grid(row=2, sticky=W, column=2)
# Example of what happens without columnspan
Button(master, text = "OK", command=quit_loop).grid(row=3, sticky=W)
master.mainloop()
print selection
Tip
If this simple GUI remains this small, it's ok to write code in this manner. However, expanding a lot on this further I would suggest taking an object oriented approach as it really improves readability a lot, especially when functions are being defined. That way they don't have to be necessarily defined beforehand.
Instead of directly using master.quit in the Button's command, define a function that finishes up the program then calls master.quit():
def end_program(event=None):#event will let it be used as .bind callbacks too if you need it.
selection = var.get()
if selection:
NotImplemented
else:
NotImplemented
master.quit()
...
Button(master, text = "OK", command = end_program).grid(row=3, sticky=W)
one the master is closed some of the data from the widgets is cleaned up so master.quit() needs to be called only after you are done accessing the widgets.
As set the selection value will be set before the window appears (selection = 0).
If you want to run tests after mainloop(), selection = var.get() should also be after mainloop() with tests.
If you do not want to close the master window before tests, use command=function:
from Tkinter import *
def function():
selection = var.get()
if selection == 1:
# Default
elif selection == 2:
# User-defined
else:#selection==0
#No choice
master.quit()
master = Tk()
var = IntVar()
Label(master, text = "Select OCR language").grid(row=0, sticky=W)
Radiobutton(master, text = "default", variable = var, value = 1).grid(row=1, sticky=W)
Radiobutton(master, text = "user-defined", variable = var, value = 2).grid(row=2, sticky=W)
Button(master, text = "OK", command = function).grid(row=3, sticky=W)
mainloop()

Python's tkinter smart entry password

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()

Categories

Resources