Change the label text, Tkinter - python

Here, is my code snippet:
def message(name, button):
button['state'] = DISABLED
mgs_label = ttk.Label(root)
if button["text"] == "Encryption":
mgs_label.pack_forget()
mgs = encryption(name)
mgs_label = ttk.Label(root, text=mgs).pack(side=LEFT)
if button["text"] == "Decryption":
mgs_label.pack_forget()
mgs = decryption(name)
mgs_label = ttk.Label(root, text=mgs).pack(side=LEFT)
When i am click the button whether it is encryption button or decryption button it is comes at mentioned position.
Here is the snapshot :
image1
And When i am click the another button the text comes after the previous one, i want to remove the previous text and then the last mgs should be displayed.
second snapshot : image2
Even i tried to make global variables but then the problem is encryption or decryption is done but the mgs is not showing on the GUI here is the code for that :
encryption_label = ttk.Label(root)
decryption_label = ttk.Label(root)
def message(name, button):
button['state'] = DISABLED
global encryption_label, decryption_label
if button["text"] == "Encryption":
if decryption_label.winfo_exists():
decryption_label.pack_forget()
mgs = encryption(name)
encryption_label["text"] = mgs
encryption_label.pack(side=LEFT)
if button["text"] == "Decryption":
if encryption_label.winfo_exists():
encryption_label.pack_forget()
mgs = decryption(name)
decryption_label["text"] = mgs
decryption_label.pack(side=LEFT)

I suggest creating the label only once and use label.configure to change the text.
You should provide a working example instead of a code snippet. I made one for you.
Thank you for your question.
import tkinter as tk
from tkinter import ttk
def e():
message(None,x_button)
def d():
message(None,y_button)
def message(name, button):
#button['state'] = tk.DISABLED
if button["text"] == "Encryption":
mgs_label.configure(text = 'encrypted stuff')
if button["text"] == "Decryption":
mgs_label.configure(text = 'decrypted stuff')
root = tk.Tk()
x_button = tk.Button(root,text = 'Encryption',
command = e)
y_button = tk.Button(root,text = 'Decryption',
command = d )
mgs_label = ttk.Label(root)
y_button.pack()
x_button.pack()
mgs_label.pack()
root.mainloop()

Related

Is there a way to create a second window that connects to the parent window like a dropdown menu

I'm trying to make it so that new information shows in in a new window, but I want the new window to be connected to the parent window, even when the parent window is clicked the new window should still show up similar to how a dropdown menu works. I'm also planning on having some of the new windows have treeviews later on.
from tkinter import *
win = Tk()
win.geometry("500x500+0+0")
def button_function ():
win2 = Toplevel()
label = Label(win2,text='dropdown', width=7)
label.pack()
win2.geometry(f"+{win.winfo_x()}+{win.winfo_y()+30}")
button = Button(win, command=lambda: button_function (), width=12)
button.pack()
win.mainloop()
Ok so with a little bit of googling I came across this post: tkinter-detecting-a-window-drag-event
In that post they show how you can keep track of when the window has moved.
By taking that code and making some small changes we can use the dragging() and stop_drag() functions to move the top level window back to where it was set to relative to the main window.
That said this will only work in this case. You will need to write something more dynamic to track any new windows you want so they are placed properly and on top of that you will probably want to build this in a class so you do not have to manage global variables.
With a combination of this tracking function and using lift() to bring the window up we get closer to what you are asking to do.
That said you will probably want remove the tool bar at the top of the root window to be more clean. I would also focus on using a dictionary or list to keep track of open and closed windows and their locations to make the dynamic part of this easier.
import tkinter as tk
win = tk.Tk()
win.geometry("500x500+0+0")
win2 = None
drag_id = ''
def dragging(event):
global drag_id
if event.widget is win:
if drag_id == '':
print('start drag')
else:
win.after_cancel(drag_id)
print('dragging')
drag_id = win.after(100, stop_drag)
if win2 is not None:
win2.lift()
win2.geometry(f"+{win.winfo_x()}+{win.winfo_y() + 30}")
def stop_drag():
global drag_id, win2, win
print('stop drag')
drag_id = ''
if win2 is not None:
win2.lift()
win2.geometry(f"+{win.winfo_x()}+{win.winfo_y() + 30}")
win.bind('<Configure>', dragging)
def button_function():
global win2
win2 = tk.Toplevel()
label = tk.Label(win2, text='drop down', width=7)
label.pack()
win2.geometry(f"+{win.winfo_x()}+{win.winfo_y()+30}")
tk.Button(win, command=button_function, width=12).pack()
win.mainloop()
EDIT:
Ok so I took some time to write this up in a class so you could see how it could be done. I have also added some level of dynamic building of the buttons and pop up windows.
We use a combination of lists and lambdas to perform a little bit of tracking and in the end we pull off exactly what you were asking for.
let me know if you have any questions.
import tkinter as tk
class Main(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('500x500')
self.pop_up_list = []
self.drag_id = ''
self.button_notes = ['Some notes for new window', 'some other notes for new window', 'bacon that is all!']
self.bind('<Configure>', self.dragging)
for ndex, value in enumerate(self.button_notes):
print(ndex)
btn = tk.Button(self, text=f'Button {ndex+1}')
btn.config(command=lambda b=btn, i=ndex: self.toggle_button_pop_ups(i, b))
btn.grid(row=ndex, column=0, padx=5, pady=5)
self.pop_up_list.append([value, 0, None, btn])
def dragging(self, event):
if event.widget is self:
if self.drag_id == '':
pass
else:
self.after_cancel(self.drag_id)
self.drag_id = self.after(100, self.stop_drag)
for p in self.pop_up_list:
if p[1] == 1:
p[2].lift()
p[2].geometry(f"+{p[3].winfo_rootx() + 65}+{p[3].winfo_rooty()}")
def stop_drag(self):
self.drag_id = ''
for p in self.pop_up_list:
if p[1] == 1:
p[2].lift()
p[2].geometry(f"+{p[3].winfo_rootx() + 65}+{p[3].winfo_rooty()}")
def toggle_button_pop_ups(self, ndex, btn):
p = self.pop_up_list
if p[ndex][1] == 0:
p[ndex][1] = 1
p[ndex][2] = tk.Toplevel(self)
p[ndex][2].overrideredirect(1)
tk.Label(p[ndex][2], text=self.pop_up_list[ndex][0]).pack()
p[ndex][2].geometry(f"+{btn.winfo_rootx() + 65}+{btn.winfo_rooty()}")
else:
p[ndex][1] = 0
p[ndex][2].destroy()
p[ndex][2] = None
if __name__ == '__main__':
Main().mainloop()

How to make tkinter entry switch between showing the text and showing a "*"

I am trying to make the entry widget show the place
holder text like this
But then when you click it it shows nothing in it like it should,
but if you click off of it shows this,
If anyone knows please let me know.
Info on what I'm doing:
This is my first GUI project I'm doing 'on my own' by that i mean no YouTube tutorial. I'm trying to make a password manager
This is my code so far:
from tkinter import *
import os
class PlaceholderEntry(Entry):
#original code at https://stackoverflow.com/questions/27820178/how-to-add-placeholder-to-an-entry-in-tkinter
#credit to Nae on stack overflow
def __init__(self, master=None, placeholder="", placefg='grey', bg='white', fg='black', insertbackground="black", show=None):
super().__init__(master)
self.placeholder = placeholder
self.placefg = placefg
self.fg = fg
self.show = show
self.none = None
self['bg'] = bg
self['insertbackground'] = insertbackground
self.bind("<FocusIn>", self.focus_in)
self.bind("<FocusOut>", self.focus_out)
self.insert_placeholder()
def insert_placeholder(self):
self.delete(0,'end')
self.insert(0, self.placeholder)
self['fg'] = self.placefg
def focus_in(self, *args):
if self['fg'] == self.placefg:
self.delete('0', 'end')
self['fg'] = self.fg
self['show'] = self.show
def focus_out(self, *args):
if not self.get():
self.insert_placeholder()
self['show'] = self.none
os.system('cls' if os.name == 'nt' else 'clear')#clears terminal
root = Tk()
root.title("entry")
root.geometry("400x400")#sets window size
root.configure(bg='#222222')#for grey background use #222222
c = ("#ffffff", "#222222", "#111111","#555555","#000000")#colors
username = Entry(root, show="*")
password = PlaceholderEntry(root, show="*", placeholder="password", placefg=c[3], bg=c[2],fg=c[0], insertbackground=c[0])
username.pack()
password.pack()
root.mainloop()

How to Update Tkinter Label while looking for keyboard input

I am Trying to make a tkinter based Cube Timer Program for which I have done a console based program before I wanted to improve on it by making a GUI for it... I have made some tkinter projects before and I have a decent knowledge of how stuff works the thing is I want the Label in the tkinter window to update in every second while listening for a spacebar key on press I couldn't figure out a way to do it can someone help me?
def on_press(key):
global chk,start,end,timer_label
print('{0} pressed'.format(key))
if key == Key.space:
if chk == True:
end = time.time()
chk = False
messagebox.showinfo('Your Time',"Your Time =>"+str(round(end-start,3)))
def on_release(key):
global chk,start,end,timer_label
if key == Key.space:
if chk == False:
start = time.time()
chk = True
with Listener(on_press=on_press,on_release=on_release) as listener:
main = tk.Tk()
main.title("Cube Timer Mark 4 Prototype")
main.resizable(0,0)
tk.Label(main, text="Cube Time Mk3 Prototype", font=['Consolas',16]).grid(row = 0,column=0)
textbox = tk.Text(main,font=['Consolas',20], height = 1,width = 27)
textbox.grid(row = 1,column=0)
textbox.insert('1.0',scrambler())
timer_frame = tk.Frame(main).grid(row=2,column=0)
global timer_label
timer_label = tk.StringVar()
timer_label.set("0.0")
tk.Label(timer_frame,text = timer_label.get()+"s",font=['Consolas',20,'bold'],pady = 25).grid(row = 2,column = 0)
main.mainloop()
This is what I have tried but didn't work
You need main.after to periodically run a function like updating the label. To listen to keyboard event, you need main.bind. See example below.
Enhancement: use tk.Label(..., textvariable=timer_label) means the label will automatically update when you set timer_label
import tkinter as tk
def key_press(event):
if event.keysym == 'space':
print('pressed')
def key_release(event):
if event.keysym == 'space':
print('released')
def update_label():
# get the time from the string
time = float(timer_label.get()[:-1])
# increment the time and put it back in timer_label
timer_label.set(str(time+1) + 's')
# calling this function again 1000ms later, which will call this again 1000ms later, ...
main.after(1000, update_label)
main = tk.Tk()
main.title("Cube Timer Mark 4 Prototype")
main.resizable(0,0)
tk.Label(main, text="Cube Time Mk3 Prototype", font=['Consolas',16]).grid(row = 0,column=0)
textbox = tk.Text(main,font=['Consolas',20], height = 1,width = 27)
textbox.grid(row = 1,column=0)
#textbox.insert('1.0',scrambler())
timer_frame = tk.Frame(main).grid(row=2,column=0)
timer_label = tk.StringVar()
timer_label.set("0.0s")
# using textvariable, you can simply update timer_label and it will be reflected
tk.Label(timer_frame,textvariable = timer_label ,font=['Consolas',20,'bold'],pady = 25).grid(row = 2,column = 0)
# bind keypress and keyrelease to the functions
main.bind("<KeyPress>", key_press)
main.bind("<KeyRelease>", key_release)
# call update label function for the first time
update_label()
main.mainloop()

Extra tk window showing in odd situation

This is my first question so be gentle!
Situation:
I have two scripts that each use tkinter to prompt for some info. They are separate because sometimes I'll need one, sometime I'll need both.
I also have a main script that imports the two tkinter scripts and calls them.
When I run each tkinter by itself, or from the main script without the other script imported, it works fine. When I import both scripts, a blank tkinter (title = "tk") window pops up.
Questions:
1. What is causing this?
2. How can I prevent that stupid window from popping up?
3. Is there an automated way to see that extra window and kill it when it does show?
What I've done:
Googled my hiney off
Renamed Tk import so each script has its own instance
Banged my head on the desk
Code:
uidpassform (first script that directly uses tkinter)
from tkinter import Tk as lf2Tk
from tkinter import Label, StringVar, Entry, Button
o_window = lf2Tk()
username = StringVar()
password = StringVar()
def close_dialog():
o_window.destroy()
def uidpass form():
#Return the value of the selected option
o_window.title('Oracle Login Credentials')
#username label and text entry box
Label(o_window, text="User Name").grid(row=2, column=0,padx = 5,pady = 20)
Entry(o_window, textvariable=username).grid(row=2, column=2, padx=20)
#password label and password entry box
Label(o_window,text="Password").grid(row=3, column=0,padx = 5)
Entry(o_window, textvariable=password, show='*').grid(row=3, column=2,padx = 20)
#login button
Button(o_window, text="Connect", command=close_dialog).grid(row=4, column=3,columnspan=2, padx = 20)
Label(o_window, text="").grid(row=5)
o_window.mainloop()
print (username.get())
print (password.get())
return [username.get(), password.get()]
if __name__ == "__main__":
uidpassform()
radiobutton form (second tkinter form)
from tkinter import Tk as rbTK
from tkinter import Radiobutton, Button, Label, IntVar, LEFT, W
rb_window = rbTK()
v = IntVar()
def validate():
#Display the value of the selected option for debugging purposes
value = v.get()
return (value)
def close_dialog():
#Check to see if the Radiobutton has a value and if so, close the form
value = v.get()
if value == 0:
value = v.get()
else:
rb_window.destroy()
def fnradiobutton():
#Return the value of the selected option
rb_window.title("Connection")
Label(rb_window, text="Choose a Data Connection:", justify=LEFT, padx=20).grid(row=0, sticky=W)
Radiobutton(rb_window, text="Production", variable=v, value=1, command=validate).grid(row=1, padx=20, sticky=W)
Radiobutton(rb_window, text="Test", variable=v, value=2, command=validate).grid(row=2, padx=20, sticky=W)
Button(rb_window, text="Done", command=close_dialog).grid(row=3, column=2, padx=10)
Label(rb_window, text="").grid(row=4)
#print(str(V.get()) + " from fnradiobutton")
rb_window.mainloop()
return v.get()
if __name__ == "__main__":
fnradiobutton()
Main script (calls the two tkinter scripts)
import cx_Oracle
import lf2 as lf
import time
import radiobutton as rb
import pyodbc
def oracle_connection():
#Get Oracle UserID and password
uidpass_list = lf.uidpassform()
#Create the connection
try:
oracle_conn = cx_Oracle.connect(uidpass_list[0], uidpass_list[1], 'robanner', encoding='UTF-8')
except:
return oracle_conn
def dbconnect(switch):
#Choose the proper connection, based on the radiobutton form
if switch == 1:
connection = pyodbc.connect('DSN=PCard_Production;Trusted_Connection=yes;')
else:
connection = pyodbc.connect('DSN=PCardTest;Trusted_Connection=yes;')
return connection
def run_script():
start = time.time()
oracle_conn = oracle_connection()
swich = rb.fnradiobutton()
conn = dbconnect(swich)
if __name__ =='__main__':
# This is the summary spot
run_script()
Try putting code for creating Root Window into functions and have them return variables. Then you have to modify your other functions to use the variables.
def initialize():
o_window = lf2Tk()
username = StringVar()
password = StringVar()
return o_window, username, password
def close_dialog(o_window):
o_window.destroy()
...
def initialize():
rb_window = rbTK()
v = IntVar()
return rb_window, v
def validate(v):
#Display the value of the selected option for debugging purposes
value = v.get()
return (value)
...
Then in your main script:
def oracle_connection():
#Get Oracle UserID and password
o_window, username, password = lf.initialize()
uidpass_list = lf.uidpassform(o_window, username, password)
#Create the connection
try:
oracle_conn = cx_Oracle.connect(uidpass_list[0], uidpass_list[1], 'robanner', encoding='UTF-8')
except:
return oracle_conn
...

2nd Page not showing up?

This is my code :
import sys
from tkinter import *
#first new screen
def next_screen(names):
for widget in names:
widget.place_forget()
buttonhyp = Button (text = "button1",fg = "blue",command = hypoténusegetdef())
buttonhyp.grid (row = 1,column = 2)
def forget_page1():
widgets = [mLabel1, button]
next_screen(widgets)
################################################################################
def hypténusegetdef ():
widgets1 = [buttonhyp]
nextscreen1(widgets1)
def next_screen(names):
for widget in names:
widget.place_forget()
hyplabel1 = Label (text = "This is my text")
#first page things
mGui = Tk ()
mGui.geometry("600x600+545+170")
mGui.title("MyMathDictionary")
mLabel1 = Label (text = "Welcome to MyMathDictionary. Press Next to continue.",
fg = "blue",bg = "white")
mLabel1.place (x= 150,y = 200)
button = Button (text = "Next", command = forget_page1 )
button.place(x = 275,y = 230)
mGui.mainloop()
What i'm trying to do is to open the program and get the user to click on "Next" and then to show another button which is called "button1" and when the user clicks on "button1" it shows up a text called which says "This is my text" in my code.But when i run it i click on "Next" and nothing shows up i checked and re- checked but nothing seems to work.Any help would be appreciated.
#
I am not an expert, but i will give it a try.
Firstly, import sys is not necessary. And importing all the objects from tkinter module using from tkinter import* is not recommended. You should use import tkinter or import tkinter as tk to avoid unexepcted consequences.
You have 2 functions with the same name. next_screen(names) which should not happen.
Instead of using widgets = [mLabel1, button] to hide the widgets, you should put them in a frame so that you can use winfo_children() to find all the children widgets.
You should put the parent widget name when you create buttons and labels. for example,
import tkinter as tk
root = tk.Tk()
mylabel = tk.Label(root,text='this is a label')
mylabel.pack()
root.mainloop()
In your first next_screen(names) function , you used grid method to display the button. You should not mix the grid method and place method.
This is something i came up with
import tkinter as tk
def Screen_1():
Clear(myframe)
mybutton2= tk.Button(myframe,text = "Button1", command = Screen_2)
mybutton2.pack()
def Screen_2():
Clear(myframe)
mylabel2= tk.Label(myframe,text = "This is my text",fg = "blue",bg = "white")
mylabel2.pack(side='top')
def Clear(parent):
for widget in parent.winfo_children():
widget.pack_forget()
root =tk.Tk()
myframe=tk.Frame(root)
myframe.pack()
mylabel1= tk.Label(myframe,text = "Welcome to MyMathDictionary. Press Next to continue.",fg = "blue",bg = "white")
mylabel1.pack(side='top')
mybutton1= tk.Button(myframe,text = "Next", command = Screen_1)
mybutton1.pack(side='bottom')
root.mainloop()
hope it helps!

Categories

Resources