Tkinter Button does nothing when clicked - python

This is the code for my personal project, for some reason, I can't get the button to do anything when pressed.
Edit: So I managed to fix the text deleting after each input, so now it will continue to output as many passwords as I want. I removed the 0.0 in output.delete so it doesn't default the text to 0 after each generated password.
from tkinter import *
from datetime import datetime
import pyperclip as pc
def close_window():
window.destroy()
exit()
# Main GUI program
window = Tk()
window.frame()
window.grid_rowconfigure((0, 1), weight=1)
window.grid_columnconfigure((0, 1), weight=1)
window.title("PW Gen")
window.geometry('+10+10')
window.configure(background="black")
Label(window, bg="black", height=0, width=25, font="Raleway").grid(row=1, column=0, sticky=NSEW)
# Enter the last 4 and generate the password
Label(window, text="Enter the last 4 digits of the Reader Name:", bg="black", fg="white", font="Raleway 12 bold").grid(row=1, column=0, sticky=W)
textentry = Entry(window, width=53, bg="white")
textentry.grid(row=2, column=0, sticky=W)
Button(window, text="Generate Password", width=16, font="Raleway 8 bold", command=click).grid(row=3, column=0, sticky=W)
# Output the password
Label(window, text="\nPassword", bg="black", fg="white", font="Raleway 12 bold").grid(row=4, column=0, sticky=W)
output = Text(window, width=40, height=4, wrap=WORD, background="white")
output.grid(row=5, column=0, columnspan=2, sticky=W)
# Button and Text To Quit GUI
Label(window, text="Click to Quit", bg="black", fg="white", font="Raleway 12 bold").grid(row=6, column=0, sticky=W)
Button(window, text="Quit", width=14, font="Raleway 8 bold", command=close_window).grid(row=7, column=0, sticky=W)
window.mainloop()

Not exactly the best solution but you can definitely give it a try.
import tkinter as tk
from datetime import datetime
import string
import pyperclip as pc
import random
root = tk.Tk()
root.title("PW Gen")
root.geometry('+10+10')
mainframe = tk.Frame(root)
text = tk.Text(root, height=5, width=25, font="Raleway")
def pwgen():
last4=text.get('1.0','end')[-5:]
j=[char for char in last4 if char in string.ascii_uppercase or char in string.ascii_lowercase]
print(j)
random.shuffle(j)
print(j)
today = datetime.today()
pw = int(today.strftime("%d")) * int(today.strftime("%m"))
last4=''.join(j)
pwgen = "$ynEL" + str(pw) + str()
pc.copy(pwgen)
print("\nThe password is $ynEL" + str(pw) + str(last4))
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.quit1 = tk.Button(self, text="QUIT", fg="black", command=self.master.destroy)
self.quit1.pack(side="top")
text.pack(side="bottom")
self.b2 = tk.Button(self)
self.create_widgets()
self.pack()
def create_widgets(self):
self.b2["text"] = "GenPW"
self.b2["command"] = pwgen
self.b2.pack(side="left")
def b1(self):
self.b2 = tk.Button(self, text="Generate PW", command=pwgen)
app = Application(root)
root.mainloop()

The code has many problems.
mainframe is not shown and never used.
Text is shown, but never used.
Text is packed inside Application but is not part of Application.
pwgen uses input and no GUI widget. A infinte loop with a GUI application is not good.
You should use the attributes of a datetime directly.
You should not generate the password at two places in the code.
You should not name a local variable like the function.
In Application you are using b1 as method, this method is overloaded by the attribute b1, so you cannot use the method anymore.
In the method b1 you are generating a new butten instead of calling the function pwgen.
import tkinter as tk
from datetime import datetime
import pyperclip as pc
def pwgen():
today = datetime.today()
pw = today.day * today.month
last4 = input("Last 4 of Reader Name [****] ")
password = f"$ynEL{pw}{last4}"
pc.copy(password)
print("\nThe password is", password)
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.quit = tk.Button(self, text="QUIT", fg="black", command=self.master.destroy)
self.quit.pack(side="top")
self.b1 = tk.Button(self, text="GenPW", command=self.click_b1)
self.b1.pack(side="left")
def click_b1(self):
pwgen()
def main():
root = tk.Tk()
root.title("PW Gen")
root.geometry('+10+10')
text = tk.Text(root, height=5, width=25, font="Raleway")
text.pack(side="bottom")
app = Application(master=root)
app.pack()
root.mainloop()
if __name__ == "__main__":
main()

This works. I have used grid manager for more control and removed unused code.
import tkinter as tk
from tkinter import *
from datetime import datetime
import pyperclip as pc
root = tk.Tk()
root.title("PW Gen")
root.geometry('+10+10')
Text = tk.Text(root, height=5, width=25, font="Raleway")
def pwgen():
while True:
today = datetime.today()
pw = int(today.strftime("%d")) * int(today.strftime("%m"))
last4 = input("Last 4 of Reader Name [****] ")
pwgen = "$ynEL" + str(pw) + str(last4)
pc.copy(pwgen)
print("\nThe password is $ynEL" + str(pw) + str(last4))
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.quit = tk.Button(self, text="QUIT", fg="black", command=self.master.destroy)
self.quit.grid(row=0,column=0,sticky=tk.EW)
Text.grid(row=1,column=0,sticky=tk.NSEW)
self.b1 = tk.Button(self, text="Generate PW", command=pwgen)
self.b1.grid(row=0,column=1,sticky=tk.EW)
self.grid(row=0,column=0,sticky=tk.NSEW)
app = Application(master=root)
root.mainloop()
A previous version created multiple Generate PW buttons.

Related

how to add admin priviledge with tkinter

I’m coding a database management app with python tkinter packages. This API is on a NAS (network attached storage). So the users can open it from a connection and make modifications in real time.
I want to give some privilege for admin users. That means if a users log in the app, they can tick and fill entry box which is disabled for normal users.
How to do it?
Here is my try:
from tkinter import *
import tkinter as tk
from tkinter import ttk
#Initialisation
root=Tk()
root.title("Test")
#Tab creation
my_tab=ttk.Notebook(root)
my_tab.pack(expand=True, fill=tk.BOTH)
#Tab name and their creation
frames=[]
nom_des_onglets=["Main", "First tab", "Second tab"]
def admin():
global longentrie
win=Toplevel()
longentrie = StringVar()
password_msg = tk.Label(win,text="Enter password for administrator privileges")
password_msg.pack()
password_entries = tk.Entry(win,textvariable=longentrie)
password_entries.pack()
tk.Button(win,text='Enter', command=admin_privilege).pack()
def admin_privilege():
global login_value
password_admin = longentrie.get()
if password_admin == 'good':
login_value=1
else:
login_value=0
for i in range(3):
frame=ttk.Frame(my_tab) # add tab
frame.pack(fill="both")
frames.append(frame)
my_tab.add(frames[i], text=nom_des_onglets[i])
#Login button
login=tk.Button(frames[0],text="login", command=admin)
login.pack()
#special priviledge
var1 = tk.IntVar()
ts = [tk.StringVar() for _ in range(17)]
lbl7 = tk.Checkbutton(frames[1], text='Text',variable=var1, onvalue=1,offvalue=0, bg='#ececec', state='disabled')
lbl7.grid(row=0, column=0, padx=5, pady=3)
lbl1=tk.Label(frames[1], text="Name")
lbl1.grid(row=2, column=0, padx=5, pady=3)
ent7=Entry(frames[1], textvariable=ts[6])
ent7.grid(row=2, column=1, padx=5, pady=3,sticky="nsew")
lbl8=tk.Label(frames[1], text="Age")
lbl8.grid(row=3, column=0, padx=5, pady=3)
ent8=Entry(frames[1], textvariable=ts[7],state='disabled')
ent8.grid(row=3, column=1, padx=5, pady=3,sticky="nsew")
if login_value == 1:
lbl7.configure(state='normal')
ent8.configure(state='normal')
root.mainloop()
Here's an example where entering the right password does correctly change the disabled state of those two fields.
This could be refactored to be a lot less messy (better variable naming for one), but it's a start:
import tkinter as tk
from tkinter import ttk
is_admin = False
def setup_ui():
lbl7.configure(state=("normal" if is_admin else "disabled"))
ent8.configure(state=("normal" if is_admin else "disabled"))
def do_login_window():
def admin_privilege():
global is_admin
if password_var.get() == "good":
is_admin = True
setup_ui()
login_win.destroy() # Close the login box
login_win = tk.Toplevel()
password_var = tk.StringVar()
password_msg = tk.Label(login_win, text="Enter password for administrator privileges")
password_msg.pack()
password_entries = tk.Entry(login_win, textvariable=password_var)
password_entries.pack()
tk.Button(login_win, text="Enter", command=admin_privilege).pack()
# Initialisation
root = tk.Tk()
root.title("Test")
# Tab creation
my_tab = ttk.Notebook(root)
my_tab.pack(expand=True, fill=tk.BOTH)
frames = []
for name in ["Main", "First tab"]:
frame = ttk.Frame(my_tab)
frame.pack(fill="both")
frames.append(frame)
my_tab.add(frame, text=name)
# Login button
login_frame = frames[0]
login = tk.Button(login_frame, text="login", command=do_login_window)
login.pack()
# special priviledge
data_frame = frames[1]
var1 = tk.IntVar()
ts = [tk.StringVar() for _ in range(17)]
lbl7 = tk.Checkbutton(
data_frame, text="Text", variable=var1, onvalue=1, offvalue=0, bg="#ececec"
)
lbl7.grid(row=0, column=0, padx=5, pady=3)
lbl1 = tk.Label(data_frame, text="Name")
lbl1.grid(row=2, column=0, padx=5, pady=3)
ent7 = tk.Entry(data_frame, textvariable=ts[6])
ent7.grid(row=2, column=1, padx=5, pady=3, sticky="nsew")
lbl8 = tk.Label(data_frame, text="Age")
lbl8.grid(row=3, column=0, padx=5, pady=3)
ent8 = tk.Entry(data_frame, textvariable=ts[7])
ent8.grid(row=3, column=1, padx=5, pady=3, sticky="nsew")
setup_ui() # Will be called after logging in too
root.mainloop()

How to seperate Tkinter Gui app source code into multiple files

i'm working on downloading manager python gui app using Tkinter and halfway there my code started to look very messy so i decided to seperate functions on different file and then import it:
my main code:
from tkinter import *
from functions import add_download
root = Tk()
root.title("The Pownloader!")
canvas = Canvas(root, width=700, height=500).pack()
# Buttons:
ADD_BUTTON = Button(root, text="ADD", bd=4, height=2, width=5, command=add_download)
SETTINGS_BUTTON = Button(root, text="SETTINGS", bd=4, height=2, width=5)
ABOUT_BUTTON = Button(root, text="ABOUT", bd=4, height=2, width=5)
EXIT_BUTTON = Button(root, text="EXIT", bd=4, height=2, width=5, command=quit)
# Mini-Buttons:
PAUSE_MINI_BUTTON = Button(root, text="PAUSE", font=(None, "8"), height=2, width=3)
RESUME_MINI_BUTTON = Button(root, text="RESUME", font=(None, "8"), height=2, width=3)
REMOVE_MINI_BUTTON = Button(root, text="REMOVE", font=(None, "8"), height=2, width=3)
# Side_Mini_Buttons:
DOWNLOAD_WINDOW = Button(root, text="Downloads", font=(None, "8"), height=3, width=6)
ERRORS_WINDOW = Button(root, text="Failed", font=(None, "8"), height=3, width=6)
COMPLETED_WINDOW = Button(root, text="Completed", font=(None, "8"), height=3, width=6)
# Positionning Buttons:
ADD_BUTTON.place(x=70, y=20)
SETTINGS_BUTTON.place(x=145, y=20)
ABOUT_BUTTON.place(x=220, y=20)
EXIT_BUTTON.place(x=295, y=20)
PAUSE_MINI_BUTTON.place(x=290, y=455)
RESUME_MINI_BUTTON.place(x=340, y=455)
REMOVE_MINI_BUTTON.place(x=390, y=455)
DOWNLOAD_WINDOW.place(x=1, y=100)
ERRORS_WINDOW.place(x=1, y=160)
COMPLETED_WINDOW.place(x=1, y=220)
# Download Frame:
DOWNLOAD_LIST_LABEL = Label(root, text="Download List:")
DOWNLOAD_LIST_LABEL.place(x=70, y=80)
DOWNLOAD_ENTRIES = Listbox(root, width=70, height=19)
DOWNLOAD_ENTRIES.place(x=70, y=100)
# Main Loop:
root.mainloop()
However my functions.py code looks like this:
def add_download():
# Defining The Pop-up frame:
top = Toplevel(root, width = 420, height = 150)
top.title("New Download")
# Putting on widgets:
link = StringVar()
LINK_LABEL = Label(top, text = "Paste Link:")
FIELD_ENTRY = Entry(top, width = 40, textvariable=link)
def on_click():
link_to_verify = (link.get()).strip()
if len(link_to_verify)>15:
if link_to_verify[0:11]=="http://www.":
DOWNLOAD_ENTRIES.insert(0, link_to_verify)
else:
print("Stupid")
else:
print("not a valid link")
BUTTONS_WIDGET = Frame(top)
ADD_BUTTON = Button(BUTTONS_WIDGET, text = "Add", width=10, command=on_click)
CANCEL_BUTTON = Button(BUTTONS_WIDGET, text = "Cancel", width=10, command=top.destroy)
# Positionning everythig:
LINK_LABEL.grid(column=0,row=0)
FIELD_ENTRY.grid(column=1,row=0)
BUTTONS_WIDGET.grid(column=1,row=2)
ADD_BUTTON.grid(column=0,row=0)
CANCEL_BUTTON.grid(column=1,row=0)
basically i wanted the function to call and show a pop-up window, i'm sure this could done in a million times better but i'm just learning, however i receive an error says:
Toplevel is not defined
Every file needs to import tkinter.
In addition, any variables in the main file which are needed by the imported functions need to be passed into the functions. For example, you should define add_download to accept the root window as a parameter.
def add_download(root):
...
Then, in the main program, pass root as that parameter:
ADD_BUTTON = Button(root, ..., command=lambda: add_download(root))
You will need to build a class to manage it.
Inside run.py:
import tkinter as tk
from interface import GUI
root = tk.Tk()
GUI(root)
Then inside your interface.py script you can call in additional modules:
import tkinter as tk
from aux import AuxGUI
from menu import MenuGUI
class GUI:
def __init__(self, master):
self.master = master
self.GUI_list = []
self.AuxGUI = AuxGUI(self.master, self.GUI_list) # Additional module
self.MenuGUI = MenuGUI (self.master, self.GUI_list) # Additional module
Then you can use OOP to access functions or objects to dynamically interact with each other.
self.GUI_list.append(self.AuxGUI)
self.GUI_list.append(self.MenuGUI)
Inside menu.py identify the correct index from the GUI_list:
import tkinter as tk
class MenuGUI:
def __init__(self, master, GUI_list):
self.master = master
self.AuxGUI = GUI_list[0]

Get the output label of calender toplevel from the master window having "Select Date" button, tkinter

I have a doubt, how to get the top-level value in the master window's label. I mean like i couldn't return the entered value from toplevel window to main's self.
I tried other ways and it didn't work
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from tkcalendar import Calendar, DateEntry
class Application(tk.Frame):
def _init_(self,master):
Frame._init_(self,master)
self.master=master
self.label=Label(text="",font=("Georgia,12"))
self.label.place(x=50,y=80)
self.create_widgets()
def calendar_view():
def print_sel():
return cal.get()
top = tk.Toplevel(root)
cal = Calendar(top,
font="Arial 14",selectmode='day',
cursor="hand1", year=2020)
cal.pack(fill="both", expand=True)
ttk.Button(top, text="ok", command=print_sel).pack()
root=tk.Tk()
s = ttk.Style(root)
s.theme_use('clam')
root.title("Date")
root.geometry("800x500")
button = tk.Button(root, text = 'Test Start Date', bg='#0073BD',height=1,width=15,padx=5,pady=2, fg="white",command=calendar_view)
button.place(x=500,y=100)
label1 = tk.Label(root, text="<-Click to select Test Start Date", padx=10, pady=10, bg="#e6e9f2", font=("calibri",8))
label1.place(x=630,y=100)
button = tk.Button(root, text = 'Test End Date', bg='#0073BD',height=1,width=15,padx=5,pady=2,fg="white",command=calendar_view)
button.place(x=500,y=150)
label1 = tk.Label(root, text="<-Click to select Test End Date", padx=10, pady=10, bg="#e6e9f2", font=("calibri",8))
label1.place(x=630,y=150)
app=Application(root)
root.configure(bg='#e6e9f2')
root.mainloop()
[here is the reference of the image]1
Suggest to use two StringVar to store the start date and end date, and pass the variable to calendar_view():
def calendar_view(var):
def print_sel():
# update the var
var.set(cal.get_date())
# close the calendar window
top.destroy()
top = tk.Toplevel(root)
cal = Calendar(top, font="Arial 14",selectmode='day',
cursor="hand1", year=2020, date_pattern='y-mm-dd')
cal.pack(fill="both", expand=True)
ttk.Button(top, text="ok", command=print_sel).pack()
# make window a modal window
top.grab_set()
top.wait_window(top)
Then update the creation of the two buttons:
button = tk.Button(root, text = 'Test Start Date', bg='#0073BD',height=1,width=15,padx=5,pady=2, fg="white",
command=lambda: calendar_view(startdate))
button = tk.Button(root, text = 'Test End Date', bg='#0073BD',height=1,width=15,padx=5,pady=2,fg="white",
command=lambda: calendar_view(enddate))
and associate the two variables to the two labels, so that their text are updated whenever the variables are updated:
startdate = tk.StringVar(value="<-Click to select Test Start Date")
label1 = tk.Label(root, textvariable=startdate, padx=10, pady=10, bg="#e6e9f2", font=("calibri",8))
enddate = tk.StringVar(value="<-Click to select Test End Date")
label2 = tk.Label(root, textvariable=enddate, padx=10, pady=10, bg="#e6e9f2", font=("calibri",8))
#acw1668 Here is the updated code, can you send me your version updated code
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from tkcalendar import Calendar, DateEntry
class Application(tk.Frame):
def _init_(self,master):
Frame._init_(self,master)
self.master=master
self.label=Label(text="",font=("Georgia,12"))
self.label.place(x=50,y=80)
self.create_widgets()
caldate1 = " "
caldate2 = " "
def calendar_view1():
def print_sel1():
global caldate1
caldate1 = cal1.selection_get()
label1.config(text = caldate1)
return caldate1
top1 = tk.Toplevel(root)
cal1 = Calendar(top1,
font="Arial 14",selectmode='day',
cursor="hand2", year=2020)
cal1.pack(fill="both", expand=True)
ttk.Button(top1, text="ok", command=print_sel1).pack()
def calendar_view2():
def print_sel2():
global caldate2
caldate2 = cal2.selection_get()
label2.config(text = caldate2)
return caldate2
top2 = tk.Toplevel(root)
cal2 = Calendar(top2,
font="Arial 14",selectmode='day',
cursor="hand2", year=2020)
cal2.pack(fill="both", expand=True)
ttk.Button(top2, text="ok", command=print_sel2).pack()
root=tk.Tk()
s = ttk.Style(root)
s.theme_use('clam')
root.title("Date")
root.geometry("800x500")
button = tk.Button(root, text = 'Test Start Date', bg='#0073BD',height=1,width=15,padx=5,pady=2, fg="white",command=calendar_view1)
button.place(x=500,y=100)
label1 = tk.Label(root, text="<-Click to select Test Start Date", padx=10, pady=10, bg="#e6e9f2", font=("calibri",8))
label1.place(x=630,y=100)
button = tk.Button(root, text = 'Test End Date', bg='#0073BD',height=1,width=15,padx=5,pady=2,fg="white",command=calendar_view2)
button.place(x=500,y=150)
label2 = tk.Label(root, text="<-Click to select Test End Date", padx=10, pady=10, bg="#e6e9f2", font=("calibri",8))
label2.place(x=630,y=150)
app=Application(root)
root.configure(bg='#e6e9f2')
root.mainloop()

Python time app, with tkinter not working

I tried making a basic time application, but, it doesn't work. If you run it, it displays the gui, the no button works (by closing the window). But, the yes button doesn't create a popup telling you the time.
from tkinter import Tk, Label, Button
from datetime import datetime
LARGE_FONT = ("Verdana", 12)
NORM_FONT = ("Helvetica", 10)
SMALL_FONT = ("Helvetica", 8)
class CurrentTime:
def __init__(self, master):
self.master = master
master.title("Current Time")
self.label = Label(master, text="Do you want to know the current time? Y/N", font=LARGE_FONT)
self.label.pack(side="top", fill="x", pady=10, padx=11)
self.time_button = Button(master, text="Yes", command=self.thetime, font=NORM_FONT)
self.time_button.pack(side="top", fill="x", pady=10, padx=11)
self.close_button = Button(master, text="No", command=master.quit, font=NORM_FONT)
self.close_button.pack(side="top", fill="x", pady=10, padx=11)
def thetime(self, master):
now = datetime.now()
current_time = now.strftime("%H:%M:%S")
master.tile("Current Time")
self.label = Label(master, text="Current Time =", command=current_time, font=LARGE_FONT)
self.label.pack(side="top", fill="x", pady=10)
self.close_button = Button(master, text="Okay", command=master.quit, font=NORM_FONT)
self.close_button.pack(side="top", fill="x", pady=10, padx=11)
root = Tk()
yes = CurrentTime(root)
root.mainloop()
Thank you for your help!
You have extra argument master in def thetime(self, master). Remove the extra argument. Also you do not need to recreate the self.label and self.close_button in the function, just update their text is enough:
def thetime(self):
self.time_button.destroy() # remove the 'Yes' button
current_time = datetime.now().strftime("%H:%M:%S")
self.label.config(text="Current Time = "+current_time) # show the current time
self.close_button.config(text="Okay") # change close_button text to 'Okay'

AttributeError in Tkinter while working with control variables in radiobuttons

I'm trying to get the value of the radiobutton selcted and storing this int into a varable. It's my first tkinter project, so I'm sorry for my probably stupid mistakes...
from tkinter import *
from tkinter import ttk
select = "A"
def begin():
grand = Tk()
grand.title("Converter")
window.destroy()
frame = Frame(grand)
option = IntVar()
-> AttributeError: 'NoneType' object has no attribute '_root'
grandlabel = Label(frame, text="Choose the grand").grid(row=0, sticky=N, padx=5)
grand1 = Radiobutton(frame, text="Speed", variable=option, value=1, command=sel).grid(row=1, sticky=W)
grand2 = Radiobutton(frame, text="etc", variable=option, value=2, command=sel).grid(row=2, sticky=W)
submitgrand = Button(frame, text="Ok", command=unit).grid(row=3, sticky=W)
frame.pack()
grand.mainloop()
def sel():
global option
global select
select = option.get()
option = StringVar()
def unit():
unit = Tk()
global select
select = grandchosen
if (grandchosen == "Speed"):
Label(unit, text="Test").pack()
else:
Label(unit, text="Test2").pack()
unit.mainloop()
root = Tk()
frame = Frame(root)
welcome = ttk.Label(frame, text="Welcome!").grid(row=0, sticky=N, padx=10, pady=3)
okbutton = Button(frame, text="Ok", width=15, command=begin).grid(row=1, sticky=S, padx=20, pady=30)
frame.pack()
style = ttk.Style()
style.configure("TLabel", foreground="midnight blue", font="Times 19")
root.mainloop()
Would be great to get some help, thank you!

Categories