How to clear a label using tkinter when pressing a button? - python

I am using labels to show a generated password in my tkinter password generator program, but when I change the length of a password from a lower value than before (for example from a length of 20 to 10) the label displaying the password appears to be overwritten - it does not clear. I have searched methods to do this, but I cannot seem to find any.
Here is my code:
from tkinter import *
from random import *
import string
root = Tk()
root.wm_title("Password Generator")
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
root.geometry("1000x1000")
title = Label(topFrame, text="Length", fg="blue")
title.grid(row=3,column=5)
var = DoubleVar()
Slider_1 = Scale(root,orient=HORIZONTAL,length=32*10,from_=0,to=32, variable
= var)
Slider_1.pack()
passLen = var.get()
uppercaseLetters = "QWERTYUIOPASDFGHJKLZXCVBNM"
lowercaseLetters = "qwertyuiopasdfghjklzxcvbnm"
symbols = "!£$%^&*()_+-=}{][~##':;?>/.<,"
digits = "1234567890"
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel = Label(topFrame, text=password)
passLabel.grid(row=4, column=5)
genButton = Button(topFrame, text="Generate Password", fg="blue",
command=gen)
genButton.grid(row=1, column=5)
root.mainloop()
When I set the length to 32 characters:
And when I set the length to 6 characters it does not clear the old password label - it simply overwrites it in the middle of the old password label:

First of all, move your gen method definition to just below imports so that they're recognized in the main body. Then take your widgets and mainloop out of the method. Just configure passLabel's text when needed:
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel['text'] = password
Entire code with suggested edits been made:
from tkinter import *
from random import *
import string
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel['text'] = password
root = Tk()
root.wm_title("Password Generator")
topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
root.geometry("1000x1000")
title = Label(topFrame, text="Length", fg="blue")
title.grid(row=3,column=5)
var = DoubleVar()
Slider_1 = Scale(root,orient=HORIZONTAL,length=32*10,from_=0,to=32, variable
= var)
Slider_1.pack()
passLen = var.get()
uppercaseLetters = "QWERTYUIOPASDFGHJKLZXCVBNM"
lowercaseLetters = "qwertyuiopasdfghjklzxcvbnm"
symbols = "!£$%^&*()_+-=}{][~##':;?>/.<,"
digits = "1234567890"
passLabel = Label(topFrame)
passLabel.grid(row=4, column=5)
genButton = Button(topFrame, text="Generate Password", fg="blue",
command=gen)
genButton.grid(row=1, column=5)
root.mainloop()

Change two things:
First:
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
passLabel = Label(topFrame)
root.geometry("1000x1000")
Second:
def gen():
characters = uppercaseLetters + lowercaseLetters + symbols + digits
password = "".join(choice(characters) for x in range(int(var.get())))
passLabel.config(text=password)
passLabel.grid(row=4, column=5)

"How to clear a label using tkinter when pressing a button?"
Below is an example that clears label's text when the button is pressed:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def clear_widget_text(widget):
widget['text'] = ""
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root, text="This will be cleared.")
button = tk.Button(root, text="Clear",
command=lambda : clear_widget_text(label))
label.pack()
button.pack()
root.mainloop()
Below is an example that destroys label when button is pressed:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def clear_widget(widget):
widget.destroy()
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root, text="This will be cleared.")
button = tk.Button(root, text="Clear",
command=lambda : clear_widget(label))
label.pack()
button.pack()
root.mainloop()

Related

Destroying a label in Tk

I've wracked my brain about this. I'm new to Python and Tk,and just trying it out. I would think this would be really easy, but I can't get it. Here's my code:
from tkinter import *
window = Tk()
window.geometry = ('400x200')
mylabel = Label(window)
def button_command():
Label(window).destroy()
text = entry1.get()
selection=variable.get()
if selection == "Celsius":
f = "Fahrenheit: " + str(round((int(text) - 32) * 5/9,2))
mylabel = Label(window, text = f).pack()
else:
c = "Celsuius: " + str(round((int(int(text)) * 9/5) + 32))
mylabel = Label(window, text = c).pack()
return None
def clear_label():
mylabel.destroy()
entry1 = Entry(window, width = 20)
entry1.pack()
variable = StringVar(window)
variable.set("Fahrenheit") # default value
w = OptionMenu(window, variable, "Fahrenheit", "Celsius")
w.pack()
Button(window, text="Button", command=button_command).pack()
Button(window, text="Clear", command=clear_label).pack()
window.mainloop()
I don't get an error, but the clear_label function doesn't do anything. It doesn't return an error. It just doesn't work. Any suggestions would be appreciated. :)
You never actually packed the label into the window, therefore there was nothing to destroy. If you run this code, you can see that once packed, your function works as expected.
from tkinter import *
window = Tk()
window.geometry = ('400x200')
mylabel = Label(window, text="test")
def button_command():
Label(window).destroy()
text = entry1.get()
selection=variable.get()
if selection == "Celsius":
f = "Fahrenheit: " + str(round((int(text) - 32) * 5/9,2))
mylabel = Label(window, text = f).pack()
else:
c = "Celsuius: " + str(round((int(int(text)) * 9/5) + 32))
mylabel = Label(window, text = c).pack()
return None
def clear_label():
mylabel.destroy()
mylabel.pack
entry1 = Entry(window, width = 20)
entry1.pack()
variable = StringVar(window)
variable.set("Fahrenheit") # default value
w = OptionMenu(window, variable, "Fahrenheit", "Celsius")
mylabel.pack()
Button(window, text="Button", command=button_command).pack()
Button(window, text="Clear", command=clear_label).pack()
window.mainloop()
Not sure whether the aim of the exercise is to destroy a label or just clear the label and give it a new value. If it is the latter, it can be achieved using the text variable parameter to label.
from tkinter import *
def button_command():
text = entry1.get()
selection=variable.get()
# Change the value of the stringvar to set the new value
if selection == "Celsius":
labelvalue.set("Fahrenheit: " + str(round((int(text) - 32) * 5/9,2)))
else:
labelvalue.set("Celsuius: " + str(round((int(int(text)) * 9/5) + 32)))
return None
def clear_label():
# No need to destroy - just change the value
labelvalue.set("")
window = Tk()
window.geometry = ('400x200')
entry1 = Entry(window, width = 20)
entry1.pack()
variable = StringVar(window)
variable.set("Fahrenheit") # default value
w = OptionMenu(window, variable, "Fahrenheit", "Celsius")
w.pack()
Button(window, text="Button", command=button_command).pack()
Button(window, text="Clear", command=clear_label).pack()
# The text displayed in mylabel will be the contents of labelvalue
labelvalue = StringVar()
mylabel = Label(window, textvariable=labelvalue)
mylabel.pack()
window.mainloop()
In principle, you don't have to delete and re-create the Label, just clear the fields in the Label and in the Entry:
def clear_label():
mylabel.config(text="")
entry1.delete(0, 'end')

Python tkinter cannot print in same line?

So I am currently writing a program using python Tkinter where I enter details and it will enter each task on the same line. I left a photo of what I have done down below. I would like to have all of them print out on the same line.
I would like to have both 2s and the three buttons in the same line.
Here's my code
# This Python file uses the following encoding: utf-8
import os, sys
import tkinter as tk
from tkinter import *
from tkinter import ttk
import tkinter.font
import tkinter.messagebox
#Set up window
root = tk.Tk()
root.title("SNKRS Bot")
root.geometry("1000x600")
#Enter ID
IDHead = Label(root, text="ID:")
IDHead.grid(row=1, column=0)
IDInput = Entry(root, textvariable="", width='5')
IDInput.grid(row=1, column=1)
#Enter link
linkHead = Label(root, text="Link:")
linkHead.grid(row=2, column=0)
linkInput = Entry(root, textvariable="", width='60')
linkInput.grid(row=2, column=1)
ID = []
linkList = []
def createTask():
#Create variables for inputs
linkInput1 = linkInput.get()
IDInput1 = IDInput.get()
#Append to lists
linkList.append(linkInput1)
ID.append(IDInput1)
#print lists to check
print("ID: " + str(ID))
print("Links: " + str(linkList))
#Clear inputs
IDInput.delete(0, END)
linkInput.delete(0, END)
#Output values
# Label(root, text=(IDInput1 + " | " + linkInput1)).grid(column=0)
Label(root, text=linkInput1).grid(column=0)
Label(root, text=linkInput1).grid(column=1)
#Actions for each task
def startTask():
print("Task started")
def stopTask():
print("Task stopped")
def deleteTask():
print("Task deleted")
#Buttons for actions
startButton = tk.Button(root, text="start", command=startTask).grid(column=2)
stopButton = tk.Button(root, text="stop", command=stopTask).grid(column=3)
deleteButton = tk.Button(root, text="delete", command=deleteTask).grid(column=4)
#Create task
create = tk.Button(root, text="Create task", command=createTask)
create.grid(row=3, column=1)
root.mainloop()
Whenever you are packing a label,in the grid method you are passing only the column.by doing so,it will pack the widget in a new row.
To avoid that pass both the row and column arguments.
Ex:
Label(root,text="some text").grid(row=3,column=0)

How can I pop up a messagebox from a menu?

I am a newbie in Python. I want to create a program with Tkinter that takes the entry from the entry "box" and then compares each character of it with the charset and finally pops up a messagebox that shows the phrase. I have almost complete it but I can not make this line work:
info_menu.add_command(label="About",
command=messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017")
Full code:
from tkinter import ttk
from tkinter import *
from tkinter import messagebox
import string as s
class Bruteforcer:
def output(self, result):
self.result = result
if result == "":
messagebox.showwarning(title="Enter a Phrase",
message="Please enter a Phrase!")
else:
messagebox.showinfo(title="Phrase Found!",
message=("The process completed Successfully!\n The Phrase Found!!!!\n", result))
def submit_button_pressed(self):
entry_val = self.entry_value.get()
charset = list(s.ascii_letters + "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψω" + s.digits + s.punctuation)
result = ""
x = 0
while x <= len(entry_val)-1:
echar = entry_val[x]
for char in charset:
if char == echar:
result += echar
x += 1
break
return self.output(result)
def __init__(self, root):
self.entry_value = StringVar(root, "")
self.the_menu = Menu(root)
info_menu = Menu(self.the_menu, tearoff=0)
**info_menu.add_command(label="About",
command=messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017")**
)
info_menu.add_separator()
info_menu.add_command(label="Quit", command=root.quit)
self.the_menu.add_cascade(label="Info", menu=info_menu)
root.config(menu=self.the_menu)
text_fond = StringVar()
text_fond.set("Times")
root.title("Graphical Bruteforcer")
root.geometry("500x500")
root.resizable(width=False, height=False)
style = ttk.Style()
style.configure("TButton",
foreground="red",
fond="Times 20",
padding=10)
style.configure("TEntry",
foreground="red",
fond="Times 20",
padding=10)
style.configure("TLabel",
foreground="red",
fond="Times 35 Bold")
# ---------- Entry -----------
self.entry_value = ttk.Entry(root,
textvariable=self.entry_value, width=25, state="normal")
self.entry_value.grid(row=1, columnspan=2)
# ---------- Label ----------
self.secret_label = ttk.Label(root,
text="The Secret Phrase").grid(row=0, column=0)
# ---------- Button ---------
self.button_submit = ttk.Button(root,
text="Submit", command=self.submit_button_pressed)
self.button_submit.grid(row=1, column=2)
root = Tk()
brute = Bruteforcer(root)
root.mainloop()
As furas said in the comments, command= expects a function. So you should replace
info_menu.add_command(label="About",
command=messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017"))
by something like
def show_about():
''' show the about messagebox '''
messagebox.showwarning(message="Creator: GakPower\nVersion: 1.0.0\nCreated at 1/5/2017")
info_menu.add_command(label="About", command=show_about)

Creating new entry boxes with button Tkinter

How do i make the button to add two box (side by side) below when it is being clicked as the user decided to put more input?
def addBox():
labelframe = Tkinter.Frame()
labelframe.bind("<Add Input>", callback)
labelframe.pack()
labelframe = Tkinter.Frame()
labelFrom = Tkinter.Label(labelframe, text= "from")
labelFrom.grid(column=1, row=0)
e = Tkinter.Entry(labelframe)
e.grid(column=1, row=1)
labelTo = Tkinter.Label(labelframe, text= "to")
labelTo.grid(column=2, row=0)
e2 = Tkinter.Entry(labelframe)
e2.grid(column=2, row=1)
labelframe.pack()
addboxButton = Button( root,text='<Add Time Input>', fg="Red",command="addBox")
addboxButton.pack(side=Tkinter.TOP)
This is example how to add Entry.
Probably you get problem because you use quotation marks in command=addBox
Because you will have to get values from entries you have to remeber them on list.
I add button which print text from entries.
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
ent = Entry(root)
ent.pack()
all_entries.append( ent )
#------------------------------------
def showEntries():
for number, ent in enumerate(all_entries):
print number, ent.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
root.mainloop()
#------------------------------------
EDIT:
Example with boxes side by side.
I use new frame to keep entries side by side using grid().
This way I don't mix grid() with pack() in main window/frame.
I use len(all_entries) to get number of next free column.
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
# I use len(all_entries) to get nuber of next free column
next_column = len(all_entries)
# add label in first row
lab = Label(frame_for_boxes, text=str(next_column+1))
lab.grid(row=0, column=next_column)
# add entry in second row
ent = Entry(frame_for_boxes)
ent.grid(row=1, column=next_column)
all_entries.append( ent )
#------------------------------------
def showEntries():
for number, ent in enumerate(all_entries):
print number, ent.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
frame_for_boxes = Frame(root)
frame_for_boxes.pack()
root.mainloop()
#------------------------------------
EDIT:
Another example:
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
frame = Frame(root)
frame.pack()
Label(frame, text='From').grid(row=0, column=0)
ent1 = Entry(frame)
ent1.grid(row=1, column=0)
Label(frame, text='To').grid(row=0, column=1)
ent2 = Entry(frame)
ent2.grid(row=1, column=1)
all_entries.append( (ent1, ent2) )
#------------------------------------
def showEntries():
for number, (ent1, ent2) in enumerate(all_entries):
print number, ent1.get(), ent2.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
root.mainloop()
#------------------------------------
First of all, the indentation is a whole mess, so I don't know where does the addBox function end ..
Second, I don't think you need a button, I suppose a checkbutton will do the same thing and it's also more common and familiar to users, I once had this problem and I simply created an entry box and put above it a label indicating that it's optional, and as for code, I simply ignored it if it was empty and verified the input if I found any input ..Howerver, that was for only one entry box, and you probably will need something more complex ..
See this ..
class OptionsView(Frame):
"""Frame for options in main window"""
def __init__(self, x, y, parent):
Frame.__init__(self, parent)
self.x = x
self.y = y
self.placed = False
self.hidden = False
self.btn = Button(self, text = 'Button attached to the frame ..', command = lambda: print('Button in frame clicked ..')).pack()
def pack(self):
self.place(x = self.x, y = self.y)
self.placed = True
def toggle_view(self):
if self.hidden:
self.pack()
self.hidden = False
else:
self.place_forget()
self.hidden = True
if __name__ == '__main__':
def m_frame():
if val.get() and not options_frame.placed:
print('Showing Frame ..')
options_frame.pack()
else:
print('Toggling Frame ..')
options_frame.toggle_view()
root = Tk()
root.geometry('300x400+500+600')
root.title('Testing Hiding Frames ..')
options_frame = OptionsView(200, 300, root)
val = BooleanVar(value = False)
Checkbutton(text = 'View more Options ..', var = val, command = m_frame).place(x=root.winfo_height()/2, y=root.winfo_width()/2)
try: root.mainloop()
except e: showerror('Error!', 'It seems there\'s a problem ..', str(e))
Ofcourse you can also modify the length and the x axis of the main window if you want to be more realistic ..

Why don't any of my buttons work?

First i had the sqrt button which worked fine, and then I added the pi button, and nothing worked, i tried changing everything and i still don't know whats wrong! Please someone help.
import sys
from tkinter import *
from math import *
def sqrt_():
text = ment.get()
a = sqrt(text)
label['text'] = a
def pi_():
text = ment.get()
a = pi(text)
label_1['text'] = a
root = Tk()
root.title('Conversions')
root.geometry('400x400')
#Get square root
sqrt_button = Button(root, text='Get Square root',command= sqrt_).place(x='160', y='5')
label = Label(root, text='')
label.place(x=5, y=30)
ment = IntVar()
entry = Entry(textvariable=ment).place(x='5', y= '10 ')
#Get Pi
pi_button = Button(root, text='Get Pi',command= pi_).place(x='160', y='50')
label_1 = Label(root, text='')
label_1.place(x=55, y=200)
ment = IntVar()
entry_1 = Entry(textvariable=ment).place(x='5', y= '55 ')
root.mainloop()
First, you don't define the function pi which means when you click the second button it will fail.
Second, you redefined the ment. In this case both two entries will be bound to the same int. This means when you click the first button, it will read the value from the second entry. So change all the second ment to ment_1. The name, the name in entry and the name in pi_.
import sys
from tkinter import *
from math import *
def sqrt_():
text = ment.get()
a = sqrt(text)
label['text'] = a
def pi_():
label_1['text'] = pi
root = Tk()
root.title('Conversions')
root.geometry('400x400')
#Get square root
sqrt_button = Button(root, text='Get Square root',command= sqrt_).place(x='160', y='5')
label = Label(root, text='')
label.place(x=5, y=30)
ment = IntVar()
entry = Entry(textvariable=ment).place(x='5', y= '10 ')
#Get Pi
pi_button = Button(root, text='Get Pi',command= pi_).place(x='160', y='50')
label_1 = Label(root, text='')
label_1.place(x=55, y=200)
ment_1 = IntVar()
entry_1 = Entry(textvariable=ment_1).place(x='5', y= '55 ')
root.mainloop()
pi isn't a function it is a constant so:
def pi_():
label_1['text'] = pi

Categories

Resources