I'm trying to place a frame with a bunch of widgets inside a toplevel window for which I have created menus. When I run the program I get two separate windows (see screen grab).
What I want is to see the labels, entry boxes, buttons, etc. inside the larger "main" window.
Screenshot of actual result
Here is the code:
# Basic menubar with a few sub-menus
from tkinter import *
from tkinter import ttk
root = Tk()
root.option_add("tearOff", FALSE)
# *************** SETUP THE CONTAINERS ***********
root.title("Menu Example")
root.geometry("600x300")
#frame = ttk.Frame(root, borderwidth = 5, relief = "sunken")
#frame.grid(row=0, column=0, sticky = (N,W,E,S))
# ***************************************************
# **** Create the Menubar
win = Toplevel(root)
menubar = Menu(win)
appmenu = Menu(menubar, name='apple')
menubar.add_cascade(menu=appmenu)
appmenu.add_command(label='About My Application')
appmenu.add_separator()
win["menu"]=menubar
# Add some menus to the menubar
menu_file = Menu(menubar)
menu_edit = Menu(menubar)
menu_transform = Menu(menubar)
menubar.add_cascade(menu=menu_file, label="File") # cascade menu items add a menu to a menubar
menubar.add_cascade(menu=menu_edit, label="Edit")
# Add items to the menus
menu_file.add_command(label = "New") # command menu items add commands to a menu.
menu_file.add_command(label = "Open...")
menu_file.add_command(label = "Close")
menu_file.add_separator()
menu_file.add_command(label = "Export as ...")
menu_edit.add_command(label = "Copy")
menu_edit.add_command(label = "Paste")
menu_edit.add_cascade(menu=menu_transform, label="Transform")
menu_transform.add_command(label="group")
menu_transform.add_command(label="ungroup")
menu_transform.add_command(label="align")
#menu_edit.add_command(label = "Transform")
# *****************************************
frame = ttk.Frame(win, borderwidth = 5, relief = "sunken")
frame.grid(row=0, column=0, sticky = (N,W,E,S))
# ***************************************************
ipaddr = StringVar()
username = StringVar()
password = StringVar()
ipAddrLbl = ttk.Label(frame, text="Switch IP Address:")
ipAddrLbl.grid(column=0, row=1, sticky = W)
usernameLbl = ttk.Label(frame, text="User Name:")
usernameLbl.grid(column=0, row=2, sticky = W)
passwordLbl = ttk.Label(frame, text="Password:")
passwordLbl.grid(column=0, row=3, sticky = W)
ipaddrEntry = ttk.Entry(frame, textvariable="ipaddr")
ipaddrEntry.grid(column=1, row=1, sticky = W)
usernameEntry = ttk.Entry(frame, textvariable="username")
usernameEntry.grid(column=1, row=2, sticky = W)
passwordEntry = ttk.Entry(frame, textvariable="password", show = "*")
passwordEntry.grid(column=1, row=3, sticky = W)
loginButton = ttk.Button(frame, text = "Login")
loginButton.grid(column=0, row=4, sticky=W)
root.mainloop()
I think the best answer for this question is to iconify the root window, then you can tinker with the Toplevel to your hearts content. That way, the root main window is hidden while the mainloop is still going without dual tkinter instances. Heres the edited code with a little tweaking so that the mainloop stops when the Toplevel is closed.
# Basic menubar with a few sub-menus
from tkinter import *
from tkinter import ttk
def _delete_window():
print ("delete_window")
try:
root.destroy()
except:
pass
root = Tk()
root.option_add("tearOff", FALSE)
# *************** SETUP THE CONTAINERS ***********
root.title("Menu Example")
root.geometry("600x300")
root.iconify()
#frame = ttk.Frame(root, borderwidth = 5, relief = "sunken")
#frame.grid(row=0, column=0, sticky = (N,W,E,S))
# ***************************************************
# **** Create the Menubar
win = Toplevel(root)
win.geometry('400x150')
menubar = Menu(win)
appmenu = Menu(menubar, name='apple')
menubar.add_cascade(menu=appmenu)
appmenu.add_command(label='About My Application')
appmenu.add_separator()
win["menu"]=menubar
# Add some menus to the menubar
menu_file = Menu(menubar)
menu_edit = Menu(menubar)
menu_transform = Menu(menubar)
menubar.add_cascade(menu=menu_file, label="File") # cascade menu items add a menu to
a menubar
menubar.add_cascade(menu=menu_edit, label="Edit")
# Add items to the menus
menu_file.add_command(label = "New") # command menu items add commands to a menu.
menu_file.add_command(label = "Open...")
menu_file.add_command(label = "Close")
menu_file.add_separator()
menu_file.add_command(label = "Export as ...")
menu_edit.add_command(label = "Copy")
menu_edit.add_command(label = "Paste")
menu_edit.add_cascade(menu=menu_transform, label="Transform")
menu_transform.add_command(label="group")
menu_transform.add_command(label="ungroup")
menu_transform.add_command(label="align")
#menu_edit.add_command(label = "Transform")
# *****************************************
frame = Frame(win, borderwidth = 5, relief = "sunken")
frame.pack()
frame.place(relx=0.5, rely=0.5, anchor=CENTER)
# ***************************************************
ipaddr = StringVar()
username = StringVar()
password = StringVar()
ipAddrLbl = ttk.Label(frame, text="Switch IP Address:")
ipAddrLbl.grid(column=0, row=1, sticky = W)
usernameLbl = ttk.Label(frame, text="User Name:")
usernameLbl.grid(column=0, row=2, sticky = W)
passwordLbl = ttk.Label(frame, text="Password:")
passwordLbl.grid(column=0, row=3, sticky = W)
ipaddrEntry = ttk.Entry(frame, textvariable="ipaddr")
ipaddrEntry.grid(column=1, row=1, sticky = W)
usernameEntry = ttk.Entry(frame, textvariable="username")
usernameEntry.grid(column=1, row=2, sticky = W)
passwordEntry = ttk.Entry(frame, textvariable="password", show = "*")
passwordEntry.grid(column=1, row=3, sticky = W)
loginButton = ttk.Button(frame, text = "Login")
loginButton.grid(column=0, row=4, sticky=W)
win.protocol("WM_DELETE_WINDOW", _delete_window)
root.mainloop()
Corrected code to use Toplevel widget instead of new Tk instance:
import tkinter as tk
class Gui1:
def __init__(self, root):
self.root = root
self.frame = tk.Frame(root)
self.button = tk.Button(text="Openwindow2",
command=self.create_gui2)
self.button.grid(row=0, column=0)
self.frame.grid(row=1, column=1)
def create_gui2(self):
class Gui2:
def __init__(self, root2):
self.root2 = root2
self.frame2 = tk.Frame(root2)
self.label=tk.Label(text="Window 2")
self.label.grid(row=0,column=0)
self.frame2.grid(row=3,column=3)
root2 = tk.Toplevel()
app2 = Gui2(root2)
root = tk.Tk()
app = Gui1(root)
root.mainloop()
Related
I am trying to create Tabs in python tkinter. I would like the Tab's height to size dynamically based on its content. Below is a sample of my code
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Frames')
root.geometry('500x500')
frame1 = LabelFrame(root)
frame1.pack(padx=5, pady = 5)
notebook1 = ttk.Notebook(frame1)
notebook1.pack(pady= 5)
nbframe1 = Frame(notebook1, bg = 'white')
nbframe2 = Frame(notebook1, bg = 'grey')
nbframe1.pack(fill ='both', expand=1)
nbframe2.pack(fill ='both', expand=1)
notebook1.add(nbframe1, text= 'A Search')
notebook1.add(nbframe2, text= 'B Search')
a_label = Label(nbframe1, text= 'A_Tag', bg = 'white')
a_label.grid(row = 0, column = 0, sticky=W, padx=5)
b_label = Label(nbframe1, text= 'B_Tag', bg = 'white')
b_label.grid(row = 1, column = 0, sticky=W, padx=5)
a_text = StringVar()
a_entry = Entry(nbframe1, textvariable = a_text, width=50)
a_entry.grid(row = 0, column = 1, sticky=W, padx=5)
b_text = StringVar()
b_entry = Entry(nbframe1, textvariable = b_text, width=25)
b_entry.grid(row = 1, column = 1, sticky=W, padx=5)
root.mainloop()
From my code, the Tabs created have same height even though one is empty. This is based on the height of the Tab with content. How can i set it so that each Tab's height is based only on the contents.
You can bind a function to the virtual event <<NotebookTabChanged>> to adapt the height of the notebook to the currently selected tab using the height option of the notebook:
def on_change_tab(event):
tab = event.widget.nametowidget(event.widget.select()) # get selected tab
event.widget.configure(height=tab.winfo_reqheight()) # resize notebook
With your example:
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Frames')
root.geometry('500x500')
def on_change_tab(event):
tab = event.widget.nametowidget(event.widget.select())
event.widget.configure(height=tab.winfo_reqheight())
frame1 = LabelFrame(root)
frame1.pack(padx=5, pady=5)
notebook1 = ttk.Notebook(frame1)
notebook1.pack(pady=5)
nbframe1 = Frame(notebook1, bg='white')
nbframe2 = Frame(notebook1, bg='grey')
notebook1.add(nbframe1, text='A Search')
notebook1.add(nbframe2, text='B Search')
a_label = Label(nbframe1, text='A_Tag', bg='white')
a_label.grid(row=0, column=0, sticky=W, padx=5)
b_label = Label(nbframe1, text='B_Tag', bg='white')
b_label.grid(row=1, column=0, sticky=W, padx=5)
a_text = StringVar()
a_entry = Entry(nbframe1, textvariable=a_text, width=50)
a_entry.grid(row=0, column=1, sticky=W, padx=5)
b_text = StringVar()
b_entry = Entry(nbframe1, textvariable=b_text, width=25)
b_entry.grid(row=1, column=1, sticky=W, padx=5)
root.update_idletasks() # force display update so that the initial tab is displayed correctly
notebook1.bind('<<NotebookTabChanged>>', on_change_tab) # binding to update the height
root.mainloop()
First off, I'm new to coding. And I'm following a course on it. But in the meantime I want to test myself and figure things out for myself and "learn on the job" a bit with more hands on coding that I can use right away.
I've written below code to try and figure out to make a main window with 2 buttons. If I press a button, it should change the screen into the second/third screen. But instead if I fire up my exe.
It opens all 3 windows right away in separate windows. And once I press a button it opens another window. But what I would want is that the main window get's "updated" to show only the labels/pictures/buttons etc (which I did not include in the .py yet).
from tkinter import *
def second_window1():
second_window1 = Toplevel(main)
second_window1.title("Second window")
second_window1.geometry("414x896")
Label(second_window1, text ="This is the second window")#.pack()
def third_window1():
third_window1 = Toplevel(main)
third_window1.title("Third window")
third_window1.geometry("414x896")
Label(third_window1, text ="This is the third window")#.pack()
main = Tk()
main.title("Main Screen")
main.geometry('414x896')
main.configure(background = "azure2")
main.resizable(False, False)
Label(main, text = "Label_1", fg = "chartreuse2", bg = "ghostwhite", font = "Helvetica 16 bold").grid(row=1, column=1)
second_window = Tk()
second_window.title("Second Screen")
second_window.geometry('414x896')
second_window.configure(background = "azure2")
second_window.resizable(False, False)
Label(main, text = "Label_2", fg = "chartreuse2", bg = "ghostwhite", font = "Helvetica 16 bold").grid(row=1, column=1)
third_window = Tk()
third_window.title("Third Screen")
third_window.geometry('414x896')
third_window.configure(background = "azure2")
third_window.resizable(False, False)
Label(main, text = "Label_3", fg = "chartreuse2", bg = "ghostwhite", font = "Helvetica 16 bold").grid(row=1, column=1)
btn = Button(main, text ="Second Screen", command = second_window1).grid(row=1, column=1)
btn = Button(main, text ="Third Screen", command = third_window1).grid(row=2, column=1)
mainloop()
enter image description here
You would want to use a ttk.Notebook for that.
See e.g. at TkDocs.
An example that creates a UI using a Notebook is below.
def create_widgets(root, db):
"""Create the UI.
Arguments:
root: root window.
db: a connection to an sqlite3 database or None.
Returns:
A SimpleNamespace of widgets.
"""
# Set the font size.
default_font = nametofont("TkDefaultFont")
default_font.configure(size=12)
root.option_add("*Font", default_font)
# Common bindings
root.bind_all('q', do_q)
# SimpleNamespace to store widgets we need in the callbacks.
w = SimpleNamespace()
# Menu
menubar = tk.Menu(root)
root.config(menu=menubar)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label="Open", command=do_open)
filemenu.add_separator()
filemenu.add_command(label="Close", command=root.quit)
menubar.add_cascade(label="File", menu=filemenu)
# Notebook
n = ttk.Notebook(root)
w.n = n
n.pack(expand=1, fill='both')
f1 = ttk.Frame(n) # Pagina 1
f1.columnconfigure(1, weight=1)
f1.rowconfigure(1, weight=1)
w.f1 = f1
f2 = ttk.Frame(n) # Pagina 2
w.f2 = f2
f2.columnconfigure(0, weight=1)
f2.rowconfigure(0, weight=1)
f3 = ttk.Frame(n) # Pagina 3
w.f3 = f3
f3.columnconfigure(0, weight=1)
f3.rowconfigure(0, weight=1)
f4 = ttk.Frame(n)
f4.columnconfigure(0, weight=1)
f4.rowconfigure(0, weight=1)
w.f4 = f4
n.add(f2, text='Orders')
n.add(f3, text='Keywords')
n.add(f4, text="Bew. 800")
n.add(f1, text='Find')
# First row of page one
ttk.Label(f1, text='Look for:').grid(row=0, column=0, sticky='w')
ze = ttk.Entry(f1)
ze.grid(row=0, column=1, sticky='ew')
ze.bind('<Return>', do_seek)
w.ze = ze
zb = ttk.Button(
f1,
text='Execute',
command=do_seek
)
if db is None:
ze['state'] = 'disabled'
zb['state'] = 'disabled'
zb.grid(row=0, column=3, sticky='e')
w.zb = zb
# Second row of page 1
cols = ['hours']
tv = ttk.Treeview(f1, columns=cols, selectmode=None)
tv.column("#0", anchor=tk.CENTER)
tv.heading("#0", text="Datum")
tv.column("hours", anchor=tk.CENTER)
tv.heading("hours", text="Hours")
tv.grid(row=1, column=0, columnspan=4, sticky='nesw')
w.tv = tv
vsb = ttk.Scrollbar(f1, orient="vertical", command=tv.yview)
vsb.grid(row=1, column=4, sticky='ns')
tv.configure(yscrollcommand=vsb.set)
# First row of page 2
cols2 = ['order', 'hours']
tv2 = ttk.Treeview(f2, columns=cols2, selectmode=None, show='headings')
for c in cols2:
tv2.heading(c, text=c.capitalize())
tv2.column(c, anchor=tk.CENTER)
tv2.grid(row=0, column=0, sticky='nesw')
w.tv2 = tv2
vsb = ttk.Scrollbar(f2, orient="vertical", command=tv2.yview)
vsb.grid(row=0, column=1, sticky='ns')
tv2.configure(yscrollcommand=vsb.set)
# First row of page 3
cols3 = ['keyword', 'hours']
tv3 = ttk.Treeview(f3, columns=cols3, selectmode=None, show='headings')
for c in cols3:
tv3.heading(c, text=c.capitalize())
tv3.column(c, anchor=tk.CENTER)
tv3.grid(row=0, column=0, sticky='nesw')
w.tv3 = tv3
vsb = ttk.Scrollbar(f3, orient="vertical", command=tv3.yview)
vsb.grid(row=0, column=1, sticky='ns')
tv3.configure(yscrollcommand=vsb.set)
# First for of page 4
cols4 = ['order', 'hours']
tv4 = ttk.Treeview(f4, columns=cols4, selectmode=None, show='headings')
for c in cols4:
tv4.heading(c, text=c.capitalize())
tv4.column(c, anchor=tk.CENTER)
tv4.grid(row=0, column=0, sticky='nesw')
w.tv4 = tv4
vsb = ttk.Scrollbar(f4, orient="vertical", command=tv4.yview)
vsb.grid(row=0, column=1, sticky='ns')
tv4.configure(yscrollcommand=vsb.set)
return w
I have 2 different python GUI menus in 2 different scripts.
A dropdown list to select
A menu where numbers can be input and output at the same GUI
I want to merge these 2 together so that both appear in the same GUI menu.
I am having trouble doing it because the structure in both python scripts is different.
Please advice.
Sharing both scripts below:
1st one
from tkinter import *
class Custombox:
def __init__(self, title, text):
self.title = title
self.text = text
def store():
self.new = self.entry.get() # storing data from entry box onto variable
if self.new == '50': # checking
a.change('ACCEPTED') # changing text
elif self.new == '40':
a.change('Increase frequency') # else, changing text
else:
a.change('Decrease frequency') # else, changing text
self.win = Toplevel()
self.win.title(self.title)
# self.win.geometry('400x150')
self.win.wm_attributes('-topmost', True)
self.label = Label(self.win, text=self.text)
self.label.grid(row=0, column=0, pady=(20, 10), columnspan=3, sticky='w', padx=10)
self.l = Label(self.win)
self.entry = Entry(self.win, width=50)
self.entry.grid(row=1, column=1, columnspan=2, padx=10)
self.b1 = Button(self.win, text='Attack', width=10, command=store)
self.b1.grid(row=3, column=1, pady=10)
# self.b2 = Button(self.win, text='Cancel', width=10, command=self.win.destroy)
# self.b2.grid(row=3, column=2, pady=10)
def __str__(self):
return str(self.new)
def change(self, ran_text):
self.l.config(text=ran_text, font=(0, 12))
self.l.grid(row=2, column=1, columnspan=3, sticky='nsew', pady=5)
root = Tk()
root.withdraw()
a = Custombox('User learning platform', 'Select the frequency of the victim sensor.')
root.mainloop()
2nd one
from tkinter import *
root = Tk()
root.title("GUI platform")
# Add a grid
mainframe = Frame(root)
mainframe.grid(column=0,row=0, sticky=(N,W,E,S) )
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 100, padx = 100)
# Create a Tkinter variable
tkvar = StringVar(root)
# Dictionary with options
choices = { 'URM37','HC-SR04','SRF05','Parallax PING'}
tkvar.set('') # set the default option
popupMenu = OptionMenu(mainframe, tkvar, *choices)
Label(mainframe, text="Please select the type of Sensor for attack").grid(row = 1, column = 1)
popupMenu.grid(row = 2, column =1)
# on change dropdown value
def change_dropdown(*args):
if tkvar.get() == 'HC-SR04':
print( "Correct" )
else:
print("WRONG")
# link function to change dropdown
tkvar.trace('w', change_dropdown)
root.mainloop()
I am trying to have two dropdown lists bellow two labels stating what they are. The problem is whenever i run it the second list is offset to the left. This takes place in the setupPage section and looks like so:
image of the issue
I have tried lots of combinations of sticky to no avail. Any help would be appreciated.
Code:
from tkinter import *
from tkinter import ttk
root = Tk()
def startPage(root):
content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(content, text="Is this a new or existing site?",font=("arial",12)) #setup of label for screen 1
yesvar = BooleanVar() #variables for check boxes later on
novar = BooleanVar()
yesvar.set(False)
novar.set(False)
one = ttk.Checkbutton(content, text="Yes", variable=yesvar, onvalue=True) #check buttons setup
two = ttk.Checkbutton(content, text="No", variable=novar, onvalue=True)
ok = ttk.Button(content, text="New", command = nextPage) #setup for buttons screen 1
cancel = ttk.Button(content, text="Existing")
content.grid(column=0, row=0) #intilises content
#frame.grid(column=0, row=0, columnspan=3, rowspan=2)
lbl1.grid(column=0, row=0, columnspan=3,pady=10,padx=10) #places the label asking the question with a gap either side for the window bindings
#name.grid(column=3, row=1, columnspan=2)
#one.grid(column=0, row=3)
#two.grid(column=1, row=3)
ok.grid(column=0, row=1,pady=10,padx=10) #places yes button 10 away from each edge
cancel.grid(column=1, row=1,pady=10,padx=10) #as above
def setupPage(root):
content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(content, text="Select meterial 1",font=("arial",12)) #setup of label for screen 1
lbl2 = ttk.Label(content, text = "Select meterial 2" ,font = ("arial",12))
content.grid(column=0, row=0)
lbl1.grid(column=0, row=0,columnspan=1, pady=10,padx=10)
lbl2.grid(column=1,row=0,columnspan=1,pady=10,padx=10)
clicked = StringVar()
clicked.set("lo2")
clicked2 = StringVar()
clicked2.set("lo2")
drop2 = OptionMenu(root, clicked2, "lo2", "mo3", "Lo2+mo3")
drop = OptionMenu(root, clicked, "lo2", "mo3", "Lo2+mo3")
drop.grid(column=0, row=1,pady=10,padx=10,sticky=NW)
drop2.grid(column=1, row=1,pady=10,padx=10,sticky=NW)
def nextPage():
global pagenum, root
for widget in root.winfo_children():
widget.destroy()
if pagenum == 1:
setupPage(root)
pagenum = 2
else :
startPage(root)
pagenum = 1
startPage(root)
pagenum = 1
root.mainloop()
The parent of the labels and the OptionMenus are different.
Changing the parents to root instead of content seems to work
from tkinter import *
from tkinter import ttk
root = Tk()
def startPage(root):
print("oi")
content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(content, text="Is this a new or existing site?",font=("arial",12)) #setup of label for screen 1
yesvar = BooleanVar() #variables for check boxes later on
novar = BooleanVar()
yesvar.set(False)
novar.set(False)
one = ttk.Checkbutton(content, text="Yes", variable=yesvar, onvalue=True) #check buttons setup
two = ttk.Checkbutton(content, text="No", variable=novar, onvalue=True)
ok = ttk.Button(content, text="New", command = nextPage) #setup for buttons screen 1
cancel = ttk.Button(content, text="Existing")
content.grid(column=0, row=0) #intilises content
#frame.grid(column=0, row=0, columnspan=3, rowspan=2)
lbl1.grid(column=0, row=0, columnspan=3,pady=10,padx=10) #places the label asking the question with a gap either side for the window bindings
#name.grid(column=3, row=1, columnspan=2)
#one.grid(column=0, row=3)
#two.grid(column=1, row=3)
ok.grid(column=0, row=1,pady=10,padx=10) #places yes button 10 away from each edge
cancel.grid(column=1, row=1,pady=10,padx=10) #as above
def setupPage(root):
#content = ttk.Frame(root) #frame for plaing everything into
#frame = ttk.Frame(content, borderwidth=5, relief="sunken", width=200, height=100) #fram for plaxing images
lbl1 = ttk.Label(root, text="Select meterial 1",font=("arial",12)) #setup of label for screen 1
lbl2 = ttk.Label(root, text = "Select meterial 2" ,font = ("arial",12))
#content.grid(column=0, row=0)
lbl1.grid(column=0, row=0,columnspan=1, pady=10,padx=10)
lbl2.grid(column=1,row=0,columnspan=1,pady=10,padx=10)
clicked = StringVar()
clicked.set("lo2")
clicked2 = StringVar()
clicked2.set("lo2")
drop2 = OptionMenu(root, clicked2, "lo2", "mo3", "Lo2+mo3")
drop = OptionMenu(root, clicked, "lo2", "mo3", "Lo2+mo3")
drop.grid(column=0, row=1,pady=10,padx=10,sticky=NW)
drop2.grid(column=1, row=1,pady=10,padx=10,sticky=NW)
def nextPage():
print("oi2")
global pagenum, root
for widget in root.winfo_children():
widget.destroy()
if pagenum == 1:
print("oi3")
setupPage(root)
pagenum = 2
else :
startPage(root)
pagenum = 1
startPage(root)
pagenum = 1
root.mainloop()
I am trying to make text appear in an entry box in my GUI application when a button is pressed. The aim is that when one button is pressed some defined text appear int he textbook and when another button is pressed the previous entry box is cleared and different text is inserted into the same entry box.
I am new to Python and therefore unsure how to do this? So far I have got three buttons to display different text each buttony in the GUI as text rather than text in separate text boxes. Could someone help please? Here's my code currently:
`# ***** Foreword Code *****
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
def new():
tkinter.messagebox.showinfo('Window Title', 'Well, this is new...')
root = Tk()
root.title("GUI Test Version 2")
root.resizable(False, False)
root.geometry('{}x{}'.format(400, 400))
***** Main Menu *****
menu = Menu(root)
root.config(menu=menu)
subMenu = Menu(menu)
menu.add_cascade(label="File", menu=subMenu)
subMenu.add_command(label="New Experiment...", command=new)
subMenu.add_command(label="New...", command=new)
subMenu.add_separator()
subMenu.add_command(label="Exit", command=root.destroy)
editMenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editMenu)
editMenu.add_command(label="Redo", command=new)
***** Toolbar *****
toolbar = Frame(root, bg="light blue")
toolbar.pack(side=TOP, fill=X)
***** Creating Buttons *****
class App(object):
def __init__(self,root):
self.root = root
self.txt_frm = Frame(self.root, width=900, height=900)
self.txt_frm.pack(fill="both", expand=True)
button1 = Button(self.txt_frm,text="HELLO", command = self.hello_world)
button1.grid(column=0,row=2, padx=2, pady=2)
button2 = Button(self.txt_frm,text="GOODBYE", command = self.goodbye_world)
button2.grid(column=1,row=2, padx=2, pady=2)
button3 = Button(self.txt_frm,text="NEW", command = self.new_world, bg="red",fg="white")
button3.grid(column=2,row=2, padx=2, pady=2)
def hello_world(self):
label = Label(self.txt_frm,text='HELLO WORLD!')
label.grid(column=0,row=3)
def goodbye_world(self):
label = Label(self.txt_frm,text='GOODBYE WORLD!')
label.grid(column=1,row=3)
def new_world(self):
label = Label(self.txt_frm,text='THIS IS A NEW WORLD!')
label.grid(column=2,row=3)
***** Status Bar *****
status = Label(root, text="Preparing to begin...", bd=1, relief=SUNKEN, anchor=W) # bd = bordered, relief = , appear placed in screen, anchor = w (NESW) needs two other properties
status.pack(side=BOTTOM, fill=X)
***** Run Code *****
app = App(root)
root.mainloop()`
The usual way to read and write to an Entry is to use a StringVar as textvariable. Inspect the code below:
from tkinter import *
root = Tk()
root.geometry('300x100')
class App(object):
def __init__(self,root):
self.root = root
self.txt_frm = Frame(self.root, width=900, height=900, bg='khaki')
self.txt_frm.pack(fill="both", expand=True)
button1 = Button(self.txt_frm,text="Hello", command = self.hello_world)
button1.grid(column=0,row=2, padx=2, pady=2)
button2 = Button(self.txt_frm,text="Goodbye", command = self.goodbye_world)
button2.grid(column=1,row=2, padx=2, pady=2)
self.entry_var = StringVar()
entry = Entry(self.txt_frm, textvariable=self.entry_var)
entry.grid(column=0, row=3, columnspan=2, padx=2, pady=2)
def hello_world(self):
self.entry_var.set('Hello')
def goodbye_world(self):
self.entry_var.set('World')
app = App(root)
root.mainloop()
I'm assigning the StringVar self.entry_var to the entry. Then I use the button callback functions to alter the contents of the entry by modifying the self.entry_var.
Make a label in __init__ and use label.config(text=text) to change its text later. Here is an example code:
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
def new():
tkinter.messagebox.showinfo('Window Title', 'Well, this is new...')
root = Tk()
root.title("GUI Test Version 2")
root.resizable(False, False)
root.geometry('{}x{}'.format(400, 400))
menu = Menu(root)
root.config(menu=menu)
subMenu = Menu(menu)
menu.add_cascade(label="File", menu=subMenu)
subMenu.add_command(label="New Experiment...", command=new)
subMenu.add_command(label="New...", command=new)
subMenu.add_separator()
subMenu.add_command(label="Exit", command=root.destroy)
editMenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editMenu)
editMenu.add_command(label="Redo", command=new)
toolbar = Frame(root, bg="light blue")
toolbar.pack(side=TOP, fill=X)
class App(object):
def __init__(self,root):
self.root = root
self.txt_frm = Frame(self.root, width=900, height=900)
self.txt_frm.pack(fill="both", expand=True)
button1 = Button(self.txt_frm,text="HELLO", command = self.hello_world)
button1.grid(column=0,row=2, padx=2, pady=2)
button2 = Button(self.txt_frm,text="GOODBYE", command = self.goodbye_world)
button2.grid(column=1,row=2, padx=2, pady=2)
button3 = Button(self.txt_frm,text="NEW", command = self.new_world, bg="red",fg="white")
button3.grid(column=2,row=2, padx=2, pady=2)
self.label = Label(self.txt_frm,text='')
self.label.grid(column=0,row=3)
def hello_world(self):
self.label.config(text="HELLO WORLD!")
def goodbye_world(self):
self.label.config(text="GOODBYE WORLD!")
def new_world(self):
self.label.config(text="THIS IS A NEW WORLD!")
status = Label(root, text="Preparing to begin...", bd=1, relief=SUNKEN, anchor=W) # bd = bordered, relief = , appear placed in screen, anchor = w (NESW) needs two other properties
status.pack(side=BOTTOM, fill=X)
app = App(root)
root.mainloop()