![]() |
Centering and adding a push button to a grid window, TKinter - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: Centering and adding a push button to a grid window, TKinter (/thread-40023.html) Pages:
1
2
|
Centering and adding a push button to a grid window, TKinter - Edward_ - May-20-2023 This May be really simple, but I'm not finding enough details to help as I'm just learning TKinter. I have a simple grid sourced by a Python list, and I'm trying to center it regardless of window size, and add single push button at bottom of the window. What I have tested caused the full window to grey out. my code: import tkinter as tk from tkinter import * import tkinter.font as font window = tk.Tk() window.title("Feed Bins") window.geometry("800x400") aList = ["Bin 1", "Bin 2", "Bin 3", "Bin 4", "Bin 5","Bin 6", "Bin 7", "Bin 8", "Bin 9", "Bin 10", "Bin 11", "Bin 12", "Bin 13", "Bin 14", "Bin 15"] onList = ["Bin 3", "Bin 12", "Bin 14"] # For testing, usually empty myFont2 = font.Font(size=10) label= [0] * 15 for x in range(5): # Number of Rows for y in range(3): #Number of Colums frame = tk.Frame(master=window,relief=tk.RAISED,borderwidth=4) frame.grid(row=x, column=y, padx=5, pady=5) # line 13 label[x+(y*5)] = tk.Label(master=frame, text=aList[x+(y*5)],font=myFont2, height=3, width=20) label[x+(y*5)].pack(fill="x") def check_alerts(): global aList,onList for x in range(0,len(aList)): if aList[x] in onList: label[x].config(bg = "red") else: label[x].config(bg = "lightgrey") window.after(1000,check_alerts) check_alerts() window.mainloop() ![]() Any assistance greatly appreciated. RE: Centering and adding a label to a grid window, TKinter - deanhystad - May-21-2023 To center justify a label you set "justify = tk.CENTER". The label will have to be the same width as the buttons, so you should set sticky= "NEWS". RE: Centering and adding a label to a grid window, TKinter - menator01 - May-21-2023 Your code altered a little. Expands with the window import tkinter as tk aList = ["Bin 1", "Bin 2", "Bin 3", "Bin 4", "Bin 5","Bin 6", "Bin 7", "Bin 8", "Bin 9", "Bin 10", "Bin 11", "Bin 12", "Bin 13", "Bin 14", "Bin 15"] root = tk.Tk() root['padx'] = 5 root['pady'] = 5 root.title('Feed Bins') root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) frame = tk.Frame(root) frame['highlightbackground'] = 'black' frame['highlightcolor'] = 'black' frame['highlightthickness'] = 1 frame.grid(column=0, row=0, sticky='news', padx=5, pady=5) for x in range(5): frame.grid_rowconfigure(x, weight=3, uniform='rows') for y in range(3): frame.grid_columnconfigure(y, weight=3, uniform='cols') label = tk.Label(frame, text=aList[x+(y*5)], relief='raised', font=(None, 16, 'bold')) label['bg'] = 'red' if aList[x+(y*5)] in ['Bin 3', 'Bin 12', 'Bin 14'] else 'gray86' label.grid(column=y, row=x, sticky='news', padx=5, pady=5) btn = tk.Button(root, text='Button', font=(None, 14, 'bold')) btn.grid(column=0, row=1) root.mainloop() RE: Centering and adding a push button to a grid window, TKinter - deanhystad - May-22-2023 Sorry, I answered the wrong question again. To place a frame in the middle of the window, use "frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER)". import tkinter as tk import random class FramedLabel(tk.Frame): """A label with a frame. Looks suspiciously like a button.""" def __init__( self, parent, text="", relief=tk.RAISED, borderwidth=4, font=(None, 10), width=10, height=3, **kwargs): super().__init__( parent, relief=relief, borderwidth=borderwidth, **kwargs ) self.label = tk.Label( self, text=text, font=font, width=width, height=height ) self.label.pack() def set_color(self, color): self["bg"] = color self.label["bg"] = color class MyWindow(tk.Tk): def __init__(self): super().__init__() self.title("Feed Bins") self.geometry("800x400") frame = tk.Frame(self) frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER) self.labels = [ FramedLabel(frame, text=f"Bin {x}") for x in range(1, 16) ] for x, label in enumerate(self.labels): label.grid(row=x // 5, column=x % 5, padx=5, pady=5) label.set_color("lightgrey") button = tk.Button(frame, text="Update", command=self.check_alerts) button.grid(row=4, column=0, columnspan=5, sticky="news") def check_alerts(self): for label in self.labels: label.set_color(random.choice(("red", "lightgrey"))) MyWindow().mainloop()However, I prefer to pack the frame and set the borders to expand the window to the desired size. import tkinter as tk import random class FramedLabel(tk.Frame): """A label with a frame. Looks suspiciously like a button.""" def __init__( self, parent, text="", relief=tk.RAISED, borderwidth=4, font=(None, 10), width=10, height=3, **kwargs): super().__init__( parent, relief=relief, borderwidth=borderwidth, **kwargs ) self.label = tk.Label( self, text=text, font=font, width=width, height=height ) self.label.pack() def set_color(self, color): self["bg"] = color self.label["bg"] = color class MyWindow(tk.Tk): def __init__(self): super().__init__() self.title("Feed Bins") frame = tk.Frame(self) frame.pack(padx=100, pady=100) self.labels = [ FramedLabel(frame, text=f"Bin {x}") for x in range(1, 16) ] for x, label in enumerate(self.labels): label.grid(row=x // 5, column=x % 5, padx=5, pady=5) label.set_color("lightgrey") button = tk.Button(frame, text="Update", command=self.check_alerts) button.grid(row=4, column=0, columnspan=5, sticky="news") def check_alerts(self): for label in self.labels: label.set_color(random.choice(("red", "lightgrey"))) MyWindow().mainloop()Either way, the real trick is to create a frame that holds your labels and buttons. Pack (or grid) the labels and buttons in the frame. Place or pack the frame in the window RE: Centering and adding a push button to a grid window, TKinter - Edward_ - May-22-2023 Thanks to all, you all are a part of my TKinter crash-course. Menator01, In 'Your code altered a little' code, the onList[] in this project will be getting additions and removals every few minutes possibly, so I made this minor change: label['bg'] = 'red' if aList[x+(y*5)] in onList else 'gray86'and re-added the checkAlerts() function. Looks like my checkAlerts() function is necessary to update the label colors when the onList[] values come and go. Any thoughts why the checkAlerts() function below might cause this error within TKInter? File "/usr/lib/python3.9/tkinter/__init__.py", line 1652, in cget return self.tk.call(self._w, 'cget', '-' + key) TypeError: can only concatenate str (not "int") to str Doesn't throw this error in my original code. RE: Centering and adding a push button to a grid window, TKinter - deanhystad - May-22-2023 Post the full error trace and the code that raises the error. There is no reason to use global in this function def check_alerts(): global aList,onList # Only affects assignment. Function does not assign values to aList or onList for x in range(0,len(aList)): if aList[x] in onList: label[x].config(bg = "red") else: label[x].config(bg = "lightgrey") window.after(1000,check_alerts) RE: Centering and adding a label to a grid window, TKinter - Edward_ - May-22-2023 (May-21-2023, 01:56 AM)deanhystad Wrote: To center justify a label you set "justify = tk.CENTER". The label will have to be the same width as the buttons, so you should set sticky=using: frame = tk.Frame(master=window,relief=tk.RAISED,justify=tk.CENTER,borderwidth=4)Gives: self.tk.call( _tkinter.TclError: unknown option "-justify" RE: Centering and adding a push button to a grid window, TKinter - deanhystad - May-22-2023 From my quote (that you included in your last post). Quote:To center justify a label you set "justify = tk.CENTER"."justify" works with labels, but later I realized you weren't asking how to center a label and I wrote this post: https://python-forum.io/thread-40023-post-169617.html#pid169617 Which shows how you can center a frame using the place() command. RE: Centering and adding a push button to a grid window, TKinter - menator01 - May-24-2023 I have one more example. Doesn't use the button to update. uses after. Sometimes pulls the same bin multiple times in the comparison list though. So instead of three red labels, will get only one or two. import tkinter as tk from random import choices aList = ["Bin 1", "Bin 2", "Bin 3", "Bin 4", "Bin 5","Bin 6", "Bin 7", "Bin 8", "Bin 9", "Bin 10", "Bin 11", "Bin 12", "Bin 13", "Bin 14", "Bin 15"] def checker(root, labels): bins = choices(aList, k=3) print(bins) for label in labels: label['bg'] = 'red' if label['text'] in bins else 'gray86' root.after(1000, lambda: checker(root, labels)) root = tk.Tk() root['padx'] = 5 root['pady'] = 5 root.title('Feed Bins') root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) frame = tk.Frame(root) frame['highlightbackground'] = 'black' frame['highlightcolor'] = 'black' frame['highlightthickness'] = 1 frame.grid(column=0, row=0, sticky='news', padx=5, pady=5) _labels = [] i = 0 for x in range(5): frame.grid_rowconfigure(x, weight=3, uniform='rows') for y in range(3): frame.grid_columnconfigure(y, weight=3, uniform='cols') _labels.append(tk.Label(frame, text=aList[x+(y*5)], relief='raised', font=(None, 16, 'bold'))) _labels[i]['bg'] = 'gray86' _labels[i].grid(column=y, row=x, sticky='news', padx=5, pady=5) i+=1 btn = tk.Button(root, text='Button', font=(None, 14, 'bold')) btn.grid(column=0, row=1, pady=8) root.after(1000, lambda: checker(root, _labels)) root.mainloop() RE: Centering and adding a push button to a grid window, TKinter - Edward_ - May-25-2023 So I now have a strange error in the centering grid when I use the needed check_alerts() function from my original code. Or should I make a separate post? The error is: File "/usr/lib/python3.9/tkinter/__init__.py", line 1652, in cget return self.tk.call(self._w, 'cget', '-' + key) TypeError: can only concatenate str (not "int") to strThe full code I'm testing is below. Not sure why the check_alerts() function causes this after centering changes. import tkinter as tk aList = ["Bin 1", "Bin 2", "Bin 3", "Bin 4", "Bin 5","Bin 6", "Bin 7", "Bin 8", "Bin 9", "Bin 10", "Bin 11", "Bin 12", "Bin 13", "Bin 14", "Bin 15"] onList = ["Bin 3", "Bin 14"] #For test, usually empty root = tk.Tk() root['padx'] = 5 root['pady'] = 5 root.title('Feed Bins') root.geometry("1200x900") root.columnconfigure(0, weight=1) root.rowconfigure(0, weight=1) frame = tk.Frame(root) frame['highlightbackground'] = 'black' frame['highlightcolor'] = 'black' frame['highlightthickness'] = 1 frame.grid(column=0, row=0, sticky='nsew', padx=5, pady=5) for x in range(5): frame.grid_rowconfigure(x, weight=3, uniform='rows') for y in range(3): frame.grid_columnconfigure(y, weight=3, uniform='cols') label = tk.Label(frame, text=aList[x+(y*5)], relief='raised', font=(None, 16, 'bold')) label['bg'] = 'red' if aList[x+(y*5)] in onList else 'gray86' label.grid(column=y, row=x, sticky='nsew', padx=5, pady=5) #check_alerts() btn = tk.Button(root, text='Add item to onList', font=(None, 14, 'bold'), command = lambda: [onList.append("Bin 9"), print("Button Press")]) btn.grid(column=0, row=1) def check_alerts(): global aList,onList for x in range(0,len(aList)): if aList[x] in onList: label[x].config(bg = "red") else: label[x].config(bg = "lightgrey") root.after(1000,check_alerts) check_alerts() root.mainloop() |