Posts: 22
Threads: 7
Joined: Jan 2022
Hi, i have been struggling with this for days looking at tutorial but just can't get it, i am creating an applications, my thought is to create app, then create frames for each section then add widgets to each section, i think i have the top section done but am trying to add 2 listboxes side by side, different widths on the left of the meetings_frame then i will be adding widgets to the right results_frame , but am stuck, any help please.
from tkinter import *
app = Tk()
app.title("Race Results")
app.geometry("800x400")
app.resizable(width=False, height=False)
app.configure(bg="black")
#create frames
selection_frame = Frame(app, bg="black", width=800, height=50)
meetings_frame = Frame(app, bg="black", width=150, height=350)
mcode_frame = Frame(app, bg="black", width=50, height=350)
results_frame = Frame(app, bg="black", width=600, height=350)
#layout frames
selection_frame.pack(side=TOP)
meetings_frame.pack(side=LEFT)
mcode_frame.pack(side=LEFT)
results_frame.pack(side=RIGHT)
#create selection widget
venue_numberlabel = Label(selection_frame, bg="black", fg="white", text="Race No", font=("bold", 10), width=7)
venue_numberbox = Entry(selection_frame, bg="#403F3F", fg="white", width=4)
venues = Button(selection_frame, text="Result", bg="#403F3F", fg="white", width=8, command="")
watch = Button(selection_frame, text="Watch Race", bg="#403F3F", fg="white", width=12, command="")
listen = Button(selection_frame, text="Audio Only", bg="#403F3F", fg="white", width=12, command="")
space = Label(selection_frame, bg="black", width=40)
info = Label(selection_frame, bg="black", fg="white", text="Race Info", font=("bold", 10), width=7)
#layout selection widgets
venue_numberlabel.grid(row=0, column=0, padx=20, pady=5)
venue_numberbox.grid(row=0, column=1, padx=20, pady=5)
venues.grid(row=0, column=2, padx=20, pady=5)
watch.grid(row=0, column=3, padx=20, pady=5)
listen.grid(row=0, column=4, padx=20, pady=5)
space.grid(row=0, column=5)
info.grid(row=1, column=0, padx=20, pady=5)
#create meeting list
meetings = Listbox(meetings_frame, bg="black", fg="white", width=150, height=350)
mcode = Listbox(meetings_frame, bg="black", fg="white", width=50, height=350)
results = Label(meetings, bg="black", fg="white", text="Results", font=("bold", 10), width=600, height=350)
#layout meeting list
meetings.grid(row=0, column=0)
mcode.grid(row=0, column=1)
results.grid(row=0, column=0)
meetings.insert(END, "Meetings")
meetings.itemconfig(END, fg="orange")
mcode.insert(END, "M-Code")
mcode.itemconfig(END, fg="orange")
app.mainloop()
Posts: 379
Threads: 2
Joined: Jan 2021
It would be easier to debug if you changed the colors of the widgets and frames so that you can see what's happening. You have defined the size of the list boxes and labels way to big thinking that you are measuring in pixels when those are measured in character widths. That's why everything seems to disappear on you. See if this helps:
import tkinter as tk
app = tk.Tk()
app.title("Race Results")
app.geometry("800x400")
app.resizable(width=False, height=False)
app.configure(bg="black")
#create frames
selection_frame = tk.Frame(app, bg="blue", width=800, height=50)
meetings_frame = tk.Frame(app, bg="red", width=50, height=330)
#layout frames
selection_frame.pack(side=tk.TOP)
meetings_frame.pack(side=tk.LEFT)
#create selection widget
venue_numberlabel = tk.Label(selection_frame, bg="black", fg="white", text="Race No", font=("bold", 10), width=7)
venue_numberbox = tk.Entry(selection_frame, bg="#403F3F", fg="white", width=4)
venues = tk.Button(selection_frame, text="Result", bg="#403F3F", fg="white", width=8, command="")
watch = tk.Button(selection_frame, text="Watch Race", bg="#403F3F", fg="white", width=12, command="")
listen = tk.Button(selection_frame, text="Audio Only", bg="#403F3F", fg="white", width=12, command="")
space = tk.Label(selection_frame, bg="black", width=37)
info = tk.Label(selection_frame, bg="black", fg="white", text="Race Info", font=("bold", 10), width=7)
#layout selection widgets
venue_numberlabel.grid(row=0, column=0, padx=20, pady=5)
venue_numberbox.grid(row=0, column=1, padx=20, pady=5)
venues.grid(row=0, column=2, padx=20, pady=5)
watch.grid(row=0, column=3, padx=20, pady=5)
listen.grid(row=0, column=4, padx=20, pady=5)
space.grid(row=0, column=5)
info.grid(row=1, column=0, padx=20, pady=5)
#create meeting list
meetings = tk.Listbox(meetings_frame, bg="green", fg="white", width=10, height=5)
mcode = tk.Listbox(meetings_frame, bg="yellow", fg="white", width=10, height=5)
results = tk.Label(meetings_frame, bg="black", fg="white", text="Results", font=("bold", 10), width=10, height=1)
#layout meeting list
meetings.grid(sticky='nw', row=0, column=0)
mcode.grid(row=0, column=1)
results.grid(row=2, column=0)
meetings.insert(tk.END, "Meetings")
meetings.itemconfig(tk.END, fg="orange")
mcode.insert(tk.END, "M-Code")
mcode.itemconfig(tk.END, fg="orange")
app.mainloop ()
Posts: 22
Threads: 7
Joined: Jan 2022
Yes, i can see where i was going wrong, i see you have imported tkinter as tk then assigned that to the other elements, can i ask how this effects them differently to the way i had it?
BashBedlam likes this post
Posts: 1,145
Threads: 114
Joined: Sep 2019
Jan-29-2022, 07:05 AM
(This post was last modified: Jan-29-2022, 07:05 AM by menator01.)
It's common practice to not use wildcard imports.. That could cause problems down the road if other modules you import have the same name. It may break something.
Better to use import tkinter or import tkinter as tk .
I took a try at your design but, found some thing I don't understand. Mainly you are putting a label in the listbox. Is this where you want it?
import tkinter as tk
class Window:
def __init__(self, parent):
self.parent = parent
self.parent.rowconfigure(0, weight=1)
self.parent.columnconfigure(0, weight=1)
# Create container
container = tk.Frame(self.parent)
container.grid(column=0, row=0, sticky='news')
# Create a frame to hold top widgets
top_frame = tk.Frame(container)
top_frame['highlightbackground'] = 'lightgray'
top_frame['highlightcolor'] = 'lightgray'
top_frame['highlightthickness'] = 1
top_frame.grid(column=0, row=0, sticky='new', padx=4, pady=4)
for i in range(2, 5):
top_frame.columnconfigure(i, weight=3, uniform='buttons')
# Venue label
venue_label = tk.Label(top_frame, text='Race No.')
venue_label.grid(column=0, row=0, sticky='new', padx=8, pady=4)
# Venue entry label
venue_entry = tk.Entry(top_frame, width=8)
venue_entry.grid(column=1, row=0, sticky='new', padx=8, pady=4)
# Create buttons in a dict. None can be replaced with button commands
button = {
'Result': None,
'Watch Race': None,
'Audio Only': None
}
# Set i = 2 as I want the buttons to start in this column
i = 2
for btn, command in button.items():
btns = tk.Button(top_frame, text=btn)
btns['command'] = command
btns.grid(column=i, row=0, sticky='new', padx=8)
i += 1
# Create the info label
info_label = tk.Label(top_frame, text='Race Info.')
info_label.grid(column=0, row=1, sticky='new', padx=8)
# reated a container to hold the two listboxes
frame2 = tk.Frame(container)
frame2['highlightbackground'] = 'lightgray'
frame2['highlightcolor'] = 'lightgray'
frame2['highlightthickness'] = 1
frame2.grid(column=0, row=1, sticky='new', padx=4, pady=4)
frame2.columnconfigure(0, weight=3, uniform='listbox')
frame2.columnconfigure(2, weight=3, uniform='listbox')
# Note that listbox elements can use commands by binding them to functions
# Create the first listbox with a scrollbar and inserted data
scrollbar = tk.Scrollbar(frame2)
scrollbar.grid(column=1, row=0, sticky='ns')
meetings = tk.Listbox(frame2, yscrollcommand=scrollbar.set)
meetings.grid(column=0, row=0, sticky='news', padx=4, pady=4)
scrollbar.configure(command=meetings.yview)
for i in range(30):
meetings.insert(tk.END, f'Meeting {i}')
# Created the second listbox with a scrollbar
scrollbar2 = tk.Scrollbar(frame2)
scrollbar2.grid(column=3, row=0, sticky='ns')
mcode = tk.Listbox(frame2, yscrollcommand=scrollbar2.set)
mcode.grid(column=2, row=0, sticky='news', padx=4, pady=4)
scrollbar2.configure(command=mcode.yview)
mcode.insert(tk.END, 'M-Code')
def main():
app = tk.Tk()
app.geometry('800x400+250+250')
app.resizable(False, False)
Window(app)
app.mainloop()
main()
BashBedlam and Hilal like this post
Posts: 22
Threads: 7
Joined: Jan 2022
I made the adjustments and this is how it should look, colours added to define the areas better.
import tkinter as tk
app = tk.Tk()
app.title("Race Results")
app.geometry("800x400")
app.resizable(width=False, height=False)
app.configure(bg="black")
# create frames
selection_frame = tk.Frame(app, bg="blue", width=800, height=50)
meetings_frame = tk.Frame(app, bg="green", width=200, height=350)
results_frame = tk.Frame(app, bg="red", width=600, height=350)
# layout frames
selection_frame.pack(side=tk.TOP)
meetings_frame.pack(side=tk.LEFT)
results_frame.pack(side=tk.LEFT)
# create selection widget
venue_numberlabel = tk.Label(selection_frame, bg="blue", fg="white", text="Race No", font=("bold", 10), width=7)
venue_numberbox = tk.Entry(selection_frame, bg="#403F3F", fg="white", width=4)
venues = tk.Button(selection_frame, text="Result", bg="#403F3F", fg="white", width=8, command="")
watch = tk.Button(selection_frame, text="Watch Race", bg="#403F3F", fg="white", width=12, command="")
listen = tk.Button(selection_frame, text="Audio Only", bg="#403F3F", fg="white", width=12, command="")
space = tk.Label(selection_frame, bg="blue", width=100)
info = tk.Label(selection_frame, bg="blue", fg="white", text="Race", font=("bold", 10), width=7)
# layout selection widgets
venue_numberlabel.grid(row=0, column=0, padx=20, pady=5)
venue_numberbox.grid(row=0, column=1, padx=20, pady=5)
venues.grid(row=0, column=2, padx=20, pady=5)
watch.grid(row=0, column=3, padx=20, pady=5)
listen.grid(row=0, column=4, padx=20, pady=5)
space.grid(row=0, column=5)
info.grid(row=1, column=0, padx=20, pady=5)
# create meeting list
meetings = tk.Listbox(meetings_frame, bg="lightgrey", fg="white", width=25, height=21)
mcode = tk.Listbox(meetings_frame, bg="grey", fg="white", width=8, height=21)
# layout meeting list
meetings.grid(row=0, column=0)
mcode.grid(row=0, column=1)
##meetings labels
meetings.insert(tk.END, "Meetings")
meetings.itemconfig(tk.END, fg="orange")
mcode.insert(tk.END, "M-Code")
mcode.itemconfig(tk.END, fg="orange")
app.mainloop()
Posts: 2,168
Threads: 35
Joined: Sep 2016
Jan-29-2022, 06:51 PM
(This post was last modified: Jan-29-2022, 06:51 PM by Yoriz.)
Using classes to organise the widgets together
import tkinter as tk
class SelectionFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._create_widgets()
self._layout_widgets()
def _create_widgets(self):
self.venue_numberlabel = tk.Label(
self, bg="blue", fg="white", text="Race No", font=("bold", 10), width=7
)
self.venue_numberbox = tk.Entry(self, bg="#403F3F", fg="white", width=4)
self.venues = tk.Button(
self, text="Result", bg="#403F3F", fg="white", width=8, command=""
)
self.watch = tk.Button(
self, text="Watch Race", bg="#403F3F", fg="white", width=12, command=""
)
self.listen = tk.Button(
self, text="Audio Only", bg="#403F3F", fg="white", width=12, command=""
)
self.space = tk.Label(self, bg="blue", width=100)
self.info = tk.Label(
self, bg="blue", fg="white", text="Race", font=("bold", 10), width=7
)
def _layout_widgets(self):
self.venue_numberlabel.grid(row=0, column=0, padx=20, pady=5)
self.venue_numberbox.grid(row=0, column=1, padx=20, pady=5)
self.venues.grid(row=0, column=2, padx=20, pady=5)
self.watch.grid(row=0, column=3, padx=20, pady=5)
self.listen.grid(row=0, column=4, padx=20, pady=5)
self.space.grid(row=0, column=5)
self.info.grid(row=1, column=0, padx=20, pady=5)
class MeetingsFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._create_widgets()
self._layout_widgets()
self._insert_meetings_label()
self._insert_mcode_label()
def _create_widgets(self):
self.meetings = tk.Listbox(
self, bg="lightgrey", fg="white", width=25, height=21
)
self.mcode = tk.Listbox(self, bg="grey", fg="white", width=8, height=21)
def _layout_widgets(self):
self.meetings.grid(row=0, column=0)
self.mcode.grid(row=0, column=1)
def _insert_meetings_label(self):
self.meetings.insert(tk.END, "Meetings")
self.meetings.itemconfig(tk.END, fg="orange")
def _insert_mcode_label(self):
self.mcode.insert(tk.END, "M-Code")
self.mcode.itemconfig(tk.END, fg="orange")
class MainFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.selection_frame = SelectionFrame(self, bg="blue", width=800, height=50)
self.meetings_frame = MeetingsFrame(self, bg="green", width=200, height=350)
self.results_frame = tk.Frame(self, bg="red", width=600, height=350)
self._layout_frames()
def _layout_frames(self):
self.selection_frame.pack(side=tk.TOP)
self.meetings_frame.pack(side=tk.LEFT)
self.results_frame.pack(side=tk.LEFT)
def main():
app = tk.Tk()
app.title("Race Results")
app.geometry("800x400")
app.resizable(width=False, height=False)
app.configure(bg="black")
main_frame = MainFrame(app)
main_frame.pack()
app.mainloop()
if __name__ == "__main__":
main()
Posts: 1,145
Threads: 114
Joined: Sep 2019
You seem to have your layout the way you want now. I'm going to post my finished attempt.
import tkinter as tk
class Window:
def __init__(self, parent):
self.parent = parent
self.parent.rowconfigure(0, weight=1)
self.parent.columnconfigure(0, weight=1)
# Create container
container = tk.Frame(self.parent)
container.grid(column=0, row=0, sticky='news')
container.grid_columnconfigure(0, weight=3)
# Create a frame to hold top widgets
top_frame = tk.Frame(container)
top_frame['highlightbackground'] = 'lightgray'
top_frame['highlightcolor'] = 'lightgray'
top_frame['highlightthickness'] = 1
top_frame.grid(column=0, row=0, sticky='new', padx=4, pady=4)
for i in range(2, 7):
top_frame.columnconfigure(i, weight=2, uniform='buttons')
# Venue label
venue_label = tk.Label(top_frame, text='Race No.')
venue_label.grid(column=0, row=0, sticky='new', padx=8, pady=4)
# Venue entry label
venue_entry = tk.Entry(top_frame, width=8)
venue_entry.grid(column=1, row=0, sticky='new', padx=8, pady=4)
# Create buttons in a dict. None can be replaced with button commands
button = {
'Result': None,
'Watch Race': None,
'Audio Only': None
}
# Set i = 2 as I want the buttons to start in this column
i = 2
for btn, command in button.items():
btns = tk.Button(top_frame, text=btn)
btns['command'] = command
btns.grid(column=i, row=0, sticky='new', padx=8, pady=4)
i += 1
# Create a spacer
spacer = tk.Label(top_frame).grid(column=6, row=0)
# Create the info label
info_label = tk.Label(top_frame, text='Race Info.')
info_label.grid(column=0, row=1, sticky='new', padx=8)
# Created a container to hold the two listboxes
frame2 = tk.Frame(container)
frame2['highlightbackground'] = 'lightgray'
frame2['highlightcolor'] = 'lightgray'
frame2['highlightthickness'] = 1
frame2.grid(column=0, row=1, sticky='new', padx=4, pady=4)
frame2.grid_columnconfigure(4, weight=3)
# Note that listbox elements can use commands by binding them to functions
# Create the first listbox with a scrollbar and inserted data
scrollbar = tk.Scrollbar(frame2)
scrollbar.grid(column=1, row=0, sticky='ns')
meetings = tk.Listbox(frame2, yscrollcommand=scrollbar.set, width=24, height=19)
meetings.grid(column=0, row=0, sticky='news', padx=4, pady=4)
scrollbar.configure(command=meetings.yview)
for i in range(30):
meetings.insert(tk.END, f'Meeting {i}')
# Created the second listbox with a scrollbar
scrollbar2 = tk.Scrollbar(frame2)
scrollbar2.grid(column=3, row=0, sticky='ns')
mcode = tk.Listbox(frame2, yscrollcommand=scrollbar2.set, width=10)
mcode.grid(column=2, row=0, sticky='news', padx=4, pady=4)
scrollbar2.configure(command=mcode.yview)
mcode.insert(tk.END, 'M-Code')
# Create result label
res_frame = tk.Frame(frame2, bg='#222222')
res_frame['relief'] = 'groove'
res_frame.grid(column=4, row=0, sticky='news', padx=4, pady=4)
def main():
app = tk.Tk()
app.geometry('800x400+250+250')
app.resizable(False, False)
app.title('Race Results')
Window(app)
app.mainloop()
main()
Posts: 22
Threads: 7
Joined: Jan 2022
Thanks all for your help, the way you set out your code tells me i have a lot to learn, cheers.
|