【发布时间】:2020-01-11 16:16:34
【问题描述】:
我正在使用 Tkinter 构建我的第一个应用程序,但我遇到了类实例。 我遵循了本教程https://pythonprogramming.net/change-show-new-frame-tkinter/,但仍然存在一些问题: - 如何将控制器作为不同类中 init 行的参数? - 我想在 classB 和相反的情况下创建 classA 的实例,但我在参数上弄错了! - 关于组织代码,我创建了 2 个类(每个框架一个)和写函数相关的好类,我应该将它们分成第 3 个类吗?最方便的方法是什么? 实际上代码正在运行,但我想在第二个窗口中添加一些设置工具! 我必须做什么才能修改 SettingsPage 类中的一些参数并在 StartPage 类中更新和使用它们?例如我想修改 ecartementlogo。
setp = SettingsPage(controller, StartPage) 给我 AttributeError: type object 'StartPage' has no attribute 'tk'
抱歉发布所有代码,但我不确定我可以删除示例中的哪些内容
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()
在 SettingsPage 类中使用的这一行是可以的: startp = StartPage(controller, SettingsPage) 我会说我需要写相反的,但是我的参数有错误(控制器,StartPage)但是这个 setp = SettingsPage(controller, StartPage) 不起作用(在 StartPage 类的 init 行中)
【问题讨论】:
-
我正在尝试运行此代码以便找到您的问题,但它抱怨您正在尝试设置
self.1,这是一个语法错误。在create_img中,这还不到您的代码的一半。你能确定这实际上是正确的吗? -
您使用的是哪个版本的 Python?哪个版本的 Tkinter? (您可以通过
tk.TclVersion获得。) -
我建议您首先阅读此答案中的所有信息:stackoverflow.com/questions/7546050/…
-
@BrianOakley aut0wash 正在遵循基于该答案的教程。该教程实际上比答案包含更多信息,问题在于添加到该基本代码中的内容。
标签: python class user-interface tkinter