I'm building my first app with Tkinter and I'm stuck with instance of class. I followed this tutorial https://pythonprogramming.net/change-show-new-frame-tkinter/ but some questions remain : - how does mean controller as argument for the init line in the differents class ? - I would like to create instance of classA in classB and inversely but I'm getting wrong with arguments ! - About organisation code, I created 2 class (one for each frame) and writting function related in the good one, should I split them in a 3rd class ? What is the most convenient way ? Actualy the code is running but I would like to add some setup tools in the 2nd window ! What do I must do to can modify some parameters in the SettingsPage Class and update and use them in the StartPage class ? For example I would like to modify ecartementlogo.
setp = SettingsPage(controller, StartPage) give me AttributeError: type object 'StartPage' has no attribute 'tk'
Sorry for posting all the code but I not sure about what can I remove for the example
import tkinter as tk
from PIL import Image, ImageDraw, ImageColor, ImageFont, ImageChops, ImageColor, ImageFont, ImageTk as PIL
import os
import utilitary as utilitary
import tkinter.ttk as ttk
from tkinter import filedialog
from configparser import ConfigParser
LARGE_FONT= ("Verdana", 12)
basewidth = 400
config = ConfigParser()
config.read('config.ini')
class DotaCasterKit(tk.Tk):
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.iconbitmap(self,default='icone.ico')
tk.Tk.wm_title(self, "vs Creator")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, SettingsPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
menu = tk.Menu(container)
menu.config(background='#2B547E', fg='#2B547E')
tk.Tk.config(self, menu=menu)
file = tk.Menu(menu)
file.add_command(label="Préférences", command=self.show_settings)
file.add_command(label="Exit",command=quit)
menu.add_cascade(label="File", menu=file)
refresh = tk.Menu(menu)
menu.add_cascade(label="Refresh", menu=refresh)
def show_settings(self):
frame = self.frames[SettingsPage]
frame.tkraise()
class StartPage(tk.Frame):
def choose_background(self):
print(self.path_slogos)
self.background_file = filedialog.askopenfilename(initialdir='C:/Users/.../VS')
self.background = PIL.Image.open(self.background_file).convert('RGBA')
self.background_name = os.path.basename(self.background_file)
self.var1.set(self.background_name)
self.miniature = self.background
self.wpercent = (self.basewidth/float(self.miniature.size[0]))
self.hsize = int((float(self.miniature.size[1])*float(self.wpercent)))
self.miniature = self.miniature.resize((self.basewidth,self.hsize))
self.miniature = PIL.PhotoImage(self.miniature)
self.canvas.itemconfig(self.image_on_canvas, image =self.miniature)
def choose_slogos_path(self):
self.path_slogos = filedialog.askdirectory(initialdir='C:/Users/.../Logos')
self.var2.set(os.path.basename(self.path_slogos))
return self.path_slogos
def create_list_logos(self):
self.path_slogos = filedialog.askdirectory(initialdir='C:/Users/.../Logos')
self.var2.set("Dossier : "+os.path.basename(self.path_slogos))
self.files = []
self.list_files_names =[]
print(self.path_slogos)
for r, d, f in os.walk(self.path_slogos):
for file in f:
if '.png' in file and 'background' not in file:
self.files.append(os.path.join(r, file))
name = os.path.basename(file)
name = name[:-4]
self.list_files_names.append(name)
self.liste_1.config(values=self.list_files_names)
self.liste_2.config(values=self.list_files_names)
self.liste_1.current(0)
self.liste_2.current(0)
return self.list_files_names
def create_img(self):
self.composition = self.background
self.ecartementlogo = 550
rift_middle = ImageFont.truetype(os.path.join('C:/Users...rift/', 'fort_foundry_rift_bold.otf'), 150)
text_middle = 'VS'
text_match_format = self.entry_format_match.get()
rift_match_format = ImageFont.truetype(os.path.join('C:/Users...rift/', 'fort_foundry_rift_bold.otf'), 60)
rift_score = ImageFont.truetype(os.path.join('C:/Users...rift/', 'fort_foundry_rift_bold.otf'), 50)
self.score_1 = self.entry_score__1.get()
self.score_2 = self.entry_score__2.get()
self.1=self.liste_1.get()
self.2=self.liste_2.get()
self.logo_1 = PIL.Image.open(self.path_slogos+'/'+self.1+'.png').convert('RGBA')
self.logo_2 = PIL.Image.open(self.path_slogos+'/'+self.2+'.png').convert('RGBA')
#logo 1
self.composition = utilitary.draw_image_advanced(self.composition, self.logo_1,
[960-int(self.ecartementlogo), 550],
[None, 300],
1)
#logo 2
self.composition = utilitary.draw_image_advanced(self.composition, self.logo_2,
[960+int(self.ecartementlogo), 550],
[None, 300],
1)
image_draw = ImageDraw.Draw(self.composition)
#insert text (VS + score)
utilitary.draw_text_center_align(image_draw, [960, 450], text_middle, font=rift_middle, fill=utilitary.colors['white'])
utilitary.draw_text_center_align(image_draw, [960, 600], text_match_format, font=rift_match_format, fill=utilitary.colors['white'])
utilitary.draw_text_center_align(image_draw, [960-self.ecartementlogo, 700], self.score_1, font=rift_score, fill=utilitary.colors['light_red'])
utilitary.draw_text_center_align(image_draw, [960+self.ecartementlogo, 700], self.score_2, font=rift_score, fill=utilitary.colors['light_red'])
if self.var4.get()==0:
pass
if self.var4.get()==1:
config.set('main', 'default_file_background', self.background_file)
config.set('main', 'default_path_slogos', self.path_slogos)
with open('config.ini', 'w') as f:
config.write(f)
print(self.background_file)
print(self.path_slogos)
print("settings saved")
print("image created")
self.miniature = self.composition
self.wpercent = (self.basewidth/float(self.miniature.size[0]))
self.hsize = int((float(self.miniature.size[1])*float(self.wpercent)))
self.miniature = self.miniature.resize((self.basewidth,self.hsize))
self.miniature = PIL.PhotoImage(self.miniature)
self.canvas.itemconfig(self.image_on_canvas, image =self.miniature)
def save_img(self):
self.var5.set("Saved as " +self.1 + '_'+self.2+'.png')
self.composition.save('C:/.../'+self.1 + '_'+self.2+'.png')
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
setp = SettingsPage(controller, StartPage)
### this line don't work ### wrong arguments
self.background_file = config.get('main', 'default_file_background')
self.path_slogos = config.get('main', 'default_path_slogos')
self.group3 = tk.LabelFrame(self, text=" A & Score")
self.group3.pack (side="left", padx=5, pady=5)
self.group4 = tk.LabelFrame(self, text=" B & Score")
self.group4.pack (side="right", padx=5, pady=5)
self.liste_1 = ttk.Combobox(self.group3)
self.liste_1.pack(side="top", padx=5, pady=5)
self.liste_2 = ttk.Combobox(self.group4)
self.liste_2.pack(side="top", padx=5, pady=5)
self.liste_1, self.liste_2 = utilitary.initial_list_logos(self.path_slogos, self.liste_1, self.liste_2)
self.liste_1.current(0)
self.liste_2.current(0)
self.group1 = tk.LabelFrame(self, text="Background")
self.group1.pack (side="top", padx=5, pady=5)
self.button_choose_background_file = tk.Button(self.group1, text="Choose Background")
self.button_choose_background_file.config(command=self.choose_background)
self.button_choose_background_file.pack (side="top", padx=5, pady=5)
self.var1 = tk.StringVar()
self.var1.set(os.path.basename(self.background_file))
self.label_name_background_file = tk.Label(self.group1, textvariable=self.var1)
self.label_name_background_file.pack (side="bottom", padx=5, pady=5)
self.group2 = tk.LabelFrame(self, text="Logos s",labelanchor='ne')
self.group2.pack (side="top", padx=5, pady=5)
self.var2 = tk.StringVar()
self.var2.set("Dossier : "+os.path.basename(self.path_slogos))
self.label_path_slogo = tk.Label(self.group2, textvariable=self.var2)
self.label_path_slogo.pack (side="bottom", padx=5, pady=5)
self.button_list_logos = tk.Button(self.group2, text="Choose logos path")
self.button_list_logos.config(command=self.create_list_logos)
self.button_list_logos.pack (side="top", padx=5, pady=5)
self.score_1 = tk.StringVar()
self.score_1.set("")
self.entry_score__1 = tk.Entry(self.group3,textvariable=self.score_1, width=5, justify='center')
self.entry_score__1.pack(side="bottom", padx=5, pady=5)
self.score_2 = tk.StringVar()
self.score_2.set("")
self.entry_score__2 = tk.Entry(self.group4,textvariable=self.score_2, width=5, justify='center')
self.entry_score__2.pack(side="bottom", padx=5, pady=5)
self.button_show = tk.Button(self, text="Show Image")
self.button_show.config(command=self.create_img)
self.button_show.pack (side="bottom", padx=5, pady=5)
self.button_save_img = tk.Button(self, text="Save as image")
self.button_save_img.config(command=self.save_img)
self.button_save_img.pack (side="bottom", padx=5, pady=5)
self.var5 = tk.StringVar ()
self.var5.set('')
self.label_name_save = tk.Label(self, textvariable =self.var5)
self.label_name_save.pack (side="bottom", padx=5, pady=5)
self.format_match = tk.StringVar()
self.format_match.set("Format")
self.entry_format_match = tk.Entry(self,textvariable=self.format_match, width=10, justify='center')
self.entry_format_match.pack()
self.var4 = tk.IntVar ()
self.var4.set(0)
self.button_save_settings = tk.Checkbutton(self, text="Save settings", variable = self.var4)
self.button_save_settings.pack(side = "bottom")
self.ecartementlogo = tk.IntVar ()
self.var4.set(550)
self.background=PIL.Image.open(self.background_file).convert('RGBA')
self.basewidth = 400
self.miniature = self.background
self.wpercent = (self.basewidth/float(self.miniature.size[0]))
self.hsize = int((float(self.miniature.size[1])*float(self.wpercent)))
self.miniature = self.miniature.resize((self.basewidth,self.hsize))
print(self.miniature.size)
self.miniature = PIL.PhotoImage(self.miniature)
self.canvas = tk.Canvas(self,width=400, height=225)
self.image_on_canvas = self.canvas.create_image(0, 0, anchor="nw", image=self.miniature)
self.canvas.pack()
class SettingsPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
startp = StartPage(controller, SettingsPage)
###this line work ### arguments are correct
label = tk.Label(self, text="Page Two!!!", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button1 = tk.Button(self, text="Back to Edition Page",
command=lambda: controller.show_frame(StartPage))
button1.pack()
scale_x_logo_ = tk.Scale(self, orient='horizontal', from_=0, to=startp.background.size[0]/2,
resolution=10, length=350,
label='Placement horizontal logo', variable= startp.ecartementlogo)
scale_x_logo_.pack()
app = DotaCasterKit()
app.geometry("%dx%d%+d%+d" % (850,620,100,100))
app.mainloop()
This line used in the SettingsPage Class is ok : startp = StartPage(controller, SettingsPage) I would say I need to write the reverse one but I having error with arguments (controller, StartPage) BUT this one setp = SettingsPage(controller, StartPage) don't work (in the init line of StartPage Class)