I want to create a UX with tkinter. One of the windows of this UX ("Window1") is supposed to have 3 columns of widgets. While the middle column is distinct to the others, the left and right columns have the same layout, only provides different information. To make it more reusable I thought its good to create a class for the columns ("Column").
"Column" shall contain a button, which displays a icon instead of text. The first problem I have is, that the icon isn't displayed when the button is created within "Column". Though, it works when created in "Window1". I already found a similar question to mine (Use an image-button defined inside an object with TKinter), where the solution is to add a "self." to save the opened image. This, however, does not solve my problem.
Defining "Column" like "Window1" obviously works, but than I cannot place the entry and the text field side-by-side in the columns.
How do I need to adjust my code so that I can still use the classes I've created?
Or am I on the completely wrong way?
I use python3, VS Code and Windows.
I've reduced my code as far as I thought it still makes sense. Please tell me if there is more or different information needed :)
Thanks already
Sebastian
import tkinter as tk
from tkinter import ttk
"""define basics"""
class app(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.state('zoomed') #open app in an expanded window
#distribute 3 columns evenly
for i in range(3):
self.grid_columnconfigure(i, weight=1)
#create a frame where more windows can be stacked if needed
containerFrame = tk.Frame(self)
containerFrame.grid()
self.frames = {}
#create window to place widgets
frame = Window1(parent=containerFrame, window = self)
self.frames["window1"] = frame #store frame in dict
frame.grid(row=0, column=0, sticky="n") #place frame on the app window
"""define the window"""
class Window1(tk.Frame):
def __init__(self, parent, window):
tk.Frame.__init__(self, parent) # create working frame
columnLeft = Column(window) # create left column
columnLeft.frame.grid(row=0, column=0) # place frame of left column
columnLeft.place() # place widgets of the column
columnRight = Column(window) # create left column
columnRight.frame.grid(row=0, column=2) # place frame of left column
columnRight.place() # place widgets of the column
# this button is displayed with an icon
self.iconDetail1 = (tk.PhotoImage(file=r"icons/detail.png")).subsample(10, 10)
self.button1 = ttk.Button(window, image=self.iconDetail1, command=lambda: print("Yes"))
self.button1.grid(row=0, column=1)
"""define the columns"""
class Column():
def __init__(self, root):
self.frame = tk.Frame() # create frame for placing widgets
for i in range(3): # main column consists of 3 sub columns
self.frame.grid_columnconfigure(i, weight=1)
"""define widgets"""
#this button is placed right, but without an icon
self.iconFolder2 = (tk.PhotoImage(file=r"icons/folder.png")).subsample(4, 4) #get image
self.button2 = ttk.Button(self.frame, image=self.iconFolder2, command=lambda: print("no....")) #create button
self.text = tk.Label(self.frame, text= "show text received from button")
def place(self): #method to place widgets independently from creating an instance
self.button2.grid(row=0, column=0, sticky=tk.W)
self.text.grid(row=0, column=2, sticky=tk.E)
if __name__ == "__main__":
app = app()
app.mainloop()