如何使用 OOP 确保所有元素都显示在 Tkinter Canvas 上
How to make sure all elements show on the Tkinter Canvas using OOP
我对 python 还很陌生,正试图掌握它的 类 和功能。我之前写了一段代码,为了让它干净,我试图把它放在 类 中,但它的一些元素不再显示了。
代码应该显示一个白色圆角矩形,上面有文本和一个按钮,效果很好,但是当我添加分类时,按钮和文本不显示。
这可能只是一些很小的东西,但正如我所说,我正在努力学习 - 如何让它像使用 OOP 之前一样显示?我究竟做错了什么?感谢您的帮助!
我的代码如下。
root = Tk()
root.configure(bg="steel blue")
canvas = Canvas(root, highlightthickness=0)
canvas.config(width=350, height=250,
bg="steel blue", ) # canvas.config(width = root.winfo_screenwidth(), height = root.winfo_screenheight() )
canvas.pack()
class User_Identification(object):
def User_Id(self):
canvas.delete("all") # root.configure(bg = "white") #canvas.config(bg = "white")
canvas.config(width=505, height=505,
bg="steel blue") # canvas.config(width = root.winfo_screenwidth(), height = root.winfo_screenheight() )
box = canvas.create_rectangle(40, 20, 500, 500, fill="white", width=4)
canvas.create_text(255, 65, text="Who are you?", font=("comic sans", 30))
box2 = canvas.create_rectangle(50, 30, 450, 100, width=2)
canvas.move(box2, 9, 5)
canvas.place(relx=0.5, rely=0.5, anchor=CENTER)
User_button = Button(root, text="User", anchor=CENTER, command=Per_Form)
User_button.configure(width=45, height=6, bg="white", fg="black", border=10) # height
User_button = canvas.create_window(60, 150, anchor=NW, window=User_button)
Driver_button = Button(root, text="Driver", anchor=CENTER, command=Per_Form)
Driver_button.configure(width=45, height=6, bg="white", fg="black", border=10) # height
Driver_button = canvas.create_window(60, 300, anchor=NW, window=Driver_button)
class Rectangle:
def round_rectangle(x1, y1, x2, y2, radius=25, **kwargs): # Making of the round rectangle
points = [x1 + radius, y1,
x1 + radius, y1,
x2 - radius, y1,
x2 - radius, y1,
x2, y1,
x2, y1 + radius,
x2, y1 + radius,
x2, y2 - radius,
x2, y2 - radius,
x2, y2,
x2 - radius, y2,
x2 - radius, y2,
x1 + radius, y2,
x1 + radius, y2,
x1, y2,
x1, y2 - radius,
x1, y2 - radius,
x1, y1 + radius,
x1, y1 + radius,
x1, y1]
return canvas.create_polygon(points, **kwargs, smooth=True)
my_rectangle = round_rectangle(10, 60, 330, 250, radius=23, outline="black", fill="white", width=4)
def __init__(self, Next_button):
self.Next_button = Next_button
Next_button = Button(root, text="Next", anchor=CENTER, command=User_Identification)
Next_button.configure(width=10, bg="black", fg="blue", border=10)
canvas.create_window(500, 500, anchor=NW, window=Next_button)
def text(text):
text = canvas.create_text(170, 100, text="Hey there, welcome to DeliverToday! \nWe bring your needs right at your doorstep ~ \nhave a great journey ahead!")
canvas.place(relx=0.5, rely=0.5, anchor=CENTER)
我认为您正在尝试执行类似于以下脚本的操作。我说明了一堆不同的概念,其中一些对于您的需求来说是不必要的。阅读文档并学习计算机科学,以便您可以理解它们。
config.py
from dataclasses import dataclass, asdict
#to make things more complicated and force you to get better
#create a dataclass of default properties
@dataclass
class Button_dc:
bg: str = "white"
fg: str = "gray20"
font: str = 'Calibri 14 bold'
border:int = 10
#make a dict instance of the dataclass
DefaultButton = asdict(Button_dc())
#make a slightly different instance
UserRoleButton = asdict(Button_dc(font='Calibri 24 bold'))
shapes.py
#add more static methods that return complex shape points
class Shapes:
@staticmethod
def RoundRectangle(x1, y1, x2, y2, radius=25): # Making of the round rectangle
return [x1 + radius, y1,
x1 + radius, y1,
x2 - radius, y1,
x2 - radius, y1,
x2, y1,
x2, y1 + radius,
x2, y1 + radius,
x2, y2 - radius,
x2, y2 - radius,
x2, y2,
x2 - radius, y2,
x2 - radius, y2,
x1 + radius, y2,
x1 + radius, y2,
x1, y2,
x1, y2 - radius,
x1, y2 - radius,
x1, y1 + radius,
x1, y1 + radius,
x1, y1]
main.py
import tkinter as tk
import config as cfg
from shapes import Shapes
from enum import Enum
#entirely over-engineered for it's purpose
class Role(Enum):
User = 1
Driver = 2
class App(tk.Tk):
#width, height and title are constants of your app so, write them as such
WIDTH = 660
HEIGHT = 400
TITLE = "DeliveryToday ~ We bring your needs right to your doorstep"
def __init__(self):
tk.Tk.__init__(self)
self.configure(bg="steel blue")
self.canvas = tk.Canvas(self, bg="steel blue", highlightthickness=0)
self.canvas.pack(side='top', fill='both', expand=True)
rect = Shapes.RoundRectangle(20, 20, 640, 320, radius=60)
self.canvas.create_polygon(rect, outline="black", fill="white", width=4, smooth=True)
#simple manual text centering, also...
#making an entire function to store text is ridiculous
text = f'{"Hey there, welcome to DeliverToday!":^{48}}\n{"We bring your needs right to your doorstep.":^{40}}\n{"Have a great journey ahead!":^{46}}'
self.canvas.create_text(40, 100, anchor='nw', font='Helvetica 20 bold', text=text)
#using **kwargs makes lines a lot shorter. prepare your data, then use it
self.next_btn = tk.Button(self, text="next", command=self.user_id, **cfg.DefaultButton)
self.canvas.create_window(500, 340, anchor='nw', window=self.next_btn)
def user_id(self):
self.canvas.delete("all")
#put user id code here
self.canvas.create_rectangle(40, 20, 620, 380, fill="white", width=4)
self.canvas.create_text(255, 65, text="Choose your role?", font="comicsans 30")
#using a lambda in this way we can pass arguments to other methods
self.user_btn = tk.Button(self, text="User", command=lambda: self.user_form(Role.User), **cfg.UserRoleButton)
self.canvas.create_window(60, 280, anchor='nw', window=self.user_btn)
self.driver_btn = tk.Button(self, text="Driver", command=lambda: self.user_form(Role.Driver), **cfg.UserRoleButton)
self.canvas.create_window(180, 280, anchor='nw', window=self.driver_btn)
def user_form(self, type):
if type is Role.User:
print("this is a user")
elif type is Role.Driver:
print("this is a driver")
#use proper PEP8 to initialize your program
if __name__ == "__main__":
app = App()
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
app.resizable(width=False, height=False)
app.title(App.TITLE)
app.mainloop()
我对 python 还很陌生,正试图掌握它的 类 和功能。我之前写了一段代码,为了让它干净,我试图把它放在 类 中,但它的一些元素不再显示了。
代码应该显示一个白色圆角矩形,上面有文本和一个按钮,效果很好,但是当我添加分类时,按钮和文本不显示。
这可能只是一些很小的东西,但正如我所说,我正在努力学习 - 如何让它像使用 OOP 之前一样显示?我究竟做错了什么?感谢您的帮助!
我的代码如下。
root = Tk()
root.configure(bg="steel blue")
canvas = Canvas(root, highlightthickness=0)
canvas.config(width=350, height=250,
bg="steel blue", ) # canvas.config(width = root.winfo_screenwidth(), height = root.winfo_screenheight() )
canvas.pack()
class User_Identification(object):
def User_Id(self):
canvas.delete("all") # root.configure(bg = "white") #canvas.config(bg = "white")
canvas.config(width=505, height=505,
bg="steel blue") # canvas.config(width = root.winfo_screenwidth(), height = root.winfo_screenheight() )
box = canvas.create_rectangle(40, 20, 500, 500, fill="white", width=4)
canvas.create_text(255, 65, text="Who are you?", font=("comic sans", 30))
box2 = canvas.create_rectangle(50, 30, 450, 100, width=2)
canvas.move(box2, 9, 5)
canvas.place(relx=0.5, rely=0.5, anchor=CENTER)
User_button = Button(root, text="User", anchor=CENTER, command=Per_Form)
User_button.configure(width=45, height=6, bg="white", fg="black", border=10) # height
User_button = canvas.create_window(60, 150, anchor=NW, window=User_button)
Driver_button = Button(root, text="Driver", anchor=CENTER, command=Per_Form)
Driver_button.configure(width=45, height=6, bg="white", fg="black", border=10) # height
Driver_button = canvas.create_window(60, 300, anchor=NW, window=Driver_button)
class Rectangle:
def round_rectangle(x1, y1, x2, y2, radius=25, **kwargs): # Making of the round rectangle
points = [x1 + radius, y1,
x1 + radius, y1,
x2 - radius, y1,
x2 - radius, y1,
x2, y1,
x2, y1 + radius,
x2, y1 + radius,
x2, y2 - radius,
x2, y2 - radius,
x2, y2,
x2 - radius, y2,
x2 - radius, y2,
x1 + radius, y2,
x1 + radius, y2,
x1, y2,
x1, y2 - radius,
x1, y2 - radius,
x1, y1 + radius,
x1, y1 + radius,
x1, y1]
return canvas.create_polygon(points, **kwargs, smooth=True)
my_rectangle = round_rectangle(10, 60, 330, 250, radius=23, outline="black", fill="white", width=4)
def __init__(self, Next_button):
self.Next_button = Next_button
Next_button = Button(root, text="Next", anchor=CENTER, command=User_Identification)
Next_button.configure(width=10, bg="black", fg="blue", border=10)
canvas.create_window(500, 500, anchor=NW, window=Next_button)
def text(text):
text = canvas.create_text(170, 100, text="Hey there, welcome to DeliverToday! \nWe bring your needs right at your doorstep ~ \nhave a great journey ahead!")
canvas.place(relx=0.5, rely=0.5, anchor=CENTER)
我认为您正在尝试执行类似于以下脚本的操作。我说明了一堆不同的概念,其中一些对于您的需求来说是不必要的。阅读文档并学习计算机科学,以便您可以理解它们。
config.py
from dataclasses import dataclass, asdict
#to make things more complicated and force you to get better
#create a dataclass of default properties
@dataclass
class Button_dc:
bg: str = "white"
fg: str = "gray20"
font: str = 'Calibri 14 bold'
border:int = 10
#make a dict instance of the dataclass
DefaultButton = asdict(Button_dc())
#make a slightly different instance
UserRoleButton = asdict(Button_dc(font='Calibri 24 bold'))
shapes.py
#add more static methods that return complex shape points
class Shapes:
@staticmethod
def RoundRectangle(x1, y1, x2, y2, radius=25): # Making of the round rectangle
return [x1 + radius, y1,
x1 + radius, y1,
x2 - radius, y1,
x2 - radius, y1,
x2, y1,
x2, y1 + radius,
x2, y1 + radius,
x2, y2 - radius,
x2, y2 - radius,
x2, y2,
x2 - radius, y2,
x2 - radius, y2,
x1 + radius, y2,
x1 + radius, y2,
x1, y2,
x1, y2 - radius,
x1, y2 - radius,
x1, y1 + radius,
x1, y1 + radius,
x1, y1]
main.py
import tkinter as tk
import config as cfg
from shapes import Shapes
from enum import Enum
#entirely over-engineered for it's purpose
class Role(Enum):
User = 1
Driver = 2
class App(tk.Tk):
#width, height and title are constants of your app so, write them as such
WIDTH = 660
HEIGHT = 400
TITLE = "DeliveryToday ~ We bring your needs right to your doorstep"
def __init__(self):
tk.Tk.__init__(self)
self.configure(bg="steel blue")
self.canvas = tk.Canvas(self, bg="steel blue", highlightthickness=0)
self.canvas.pack(side='top', fill='both', expand=True)
rect = Shapes.RoundRectangle(20, 20, 640, 320, radius=60)
self.canvas.create_polygon(rect, outline="black", fill="white", width=4, smooth=True)
#simple manual text centering, also...
#making an entire function to store text is ridiculous
text = f'{"Hey there, welcome to DeliverToday!":^{48}}\n{"We bring your needs right to your doorstep.":^{40}}\n{"Have a great journey ahead!":^{46}}'
self.canvas.create_text(40, 100, anchor='nw', font='Helvetica 20 bold', text=text)
#using **kwargs makes lines a lot shorter. prepare your data, then use it
self.next_btn = tk.Button(self, text="next", command=self.user_id, **cfg.DefaultButton)
self.canvas.create_window(500, 340, anchor='nw', window=self.next_btn)
def user_id(self):
self.canvas.delete("all")
#put user id code here
self.canvas.create_rectangle(40, 20, 620, 380, fill="white", width=4)
self.canvas.create_text(255, 65, text="Choose your role?", font="comicsans 30")
#using a lambda in this way we can pass arguments to other methods
self.user_btn = tk.Button(self, text="User", command=lambda: self.user_form(Role.User), **cfg.UserRoleButton)
self.canvas.create_window(60, 280, anchor='nw', window=self.user_btn)
self.driver_btn = tk.Button(self, text="Driver", command=lambda: self.user_form(Role.Driver), **cfg.UserRoleButton)
self.canvas.create_window(180, 280, anchor='nw', window=self.driver_btn)
def user_form(self, type):
if type is Role.User:
print("this is a user")
elif type is Role.Driver:
print("this is a driver")
#use proper PEP8 to initialize your program
if __name__ == "__main__":
app = App()
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
app.resizable(width=False, height=False)
app.title(App.TITLE)
app.mainloop()