Python 3.x 在小部件创建自动调整大小(tkinter,python 3)中继承子框架
我想做的是:Python 3.x 在小部件创建自动调整大小(tkinter,python 3)中继承子框架,python-3.x,function,tkinter,frame,autosize,Python 3.x,Function,Tkinter,Frame,Autosize,我想做的是: 分别创建一个主帧(pc_gui)和两个子帧(视频_帧)和(侧帧) 允许用户调整应用程序窗口的大小以适应需要,并相应调整所有框架、小部件、图像等的大小 gui中其他位置的参考框架 为了使事情保持整洁(可能是错误的),我有一个应用程序类和函数:init、app_size、create_frames、create_widget和updater函数。还有很多,但如果我能让这个核心部分正常工作,我应该能够继续取得进展 这从相对标准的tkinter UI初始化开始,包括应用程序窗口的起始大小
# Initialize Application Window
pc_gui = tk.Tk()
pc_gui.geometry("1280x720")
# Initialize Updater Variables
UPDATE_RATE = 1000
# Run application
app = Application(pc_gui)
pc_gui.mainloop()
然后我创建了类、主框架(pc_gui),并调用了各种子框架、应用程序大小和图像函数
class Application(tk.Frame):
""" GUI """
def __init__(self, pc_gui):
""" Initialize the frame """
tk.Frame.__init__(self, pc_gui)
self.app_size()
self.grid()
self.create_frames()
self.create_images()
self.updater()
这是应用程序大小函数。它的目的是解析应用程序窗口和显示监视器的当前大小,假设用户将在程序运行时更改这些大小以适应
def app_size(self):
pc_gui.update_idletasks() # Get Current Application Values
app_width = pc_gui.winfo_width() # Current Application Width
app_height = pc_gui.winfo_height() # Current Application Height
disp_width = pc_gui.winfo_screenwidth() # Monitor (Screen) Width
disp_height = pc_gui.winfo_screenheight() # Monitor (Screen) Height
return app_width, app_height, disp_width, disp_height
然后,我使用app_大小值创建子帧。这些颜色只是为了帮助我在开发过程中跟踪事物
def create_frames(self):
""" Create Frames """
app_size = self.app_size() # Get size wxh of application window and display
app_width = app_size[0]
app_height = app_size[1]
disp_width = app_size[2]
disp_height = app_size[3]
geometry = "%dx%d" % (app_width, app_height) # Create text value for geometry
pc_gui.geometry(geometry) # Set Application Window Size
# Section of Application window dedicated to source video
video_frame = tk.Frame(
master = pc_gui,
width = app_width*.75,
height = app_height,
bg = "blue"
)
video_frame.place(
x = 0,
y = 0
)
# Section of Application window dedicated to calculations
side_frame = tk.Frame(
master = pc_gui,
width = app_width*.25,
height = app_height,
bg = "red"
)
side_frame.place(
x = app_width*.75,
y = 0
)
pc_gui.update_idletasks()
sf_x = side_frame.winfo_x()
sf_y = side_frame.winfo_y()
sf_w = side_frame.winfo_width()
sf_h = side_frame.winfo_height()
return sf_x, sf_y, sf_w, sf_h
def updater(self):
#self.create_frames() # Update Application Window
self.create_images() # Update Images Widget
self.after(UPDATE_RATE, self.updater) # Call "updater" function after 1 second
然后我开始创建小部件。对于图像(标签)小部件,我希望使用网格,但我最难弄清楚如何在create_images函数中引用子帧(side_frame)。我删去了重要的部分,使这个问题更切题
def create_images(self):
sf_dims = self.create_frames()
sf_x = sf_dims[0]
sf_y = sf_dims[1]
sf_w = sf_dims[2]
sf_h = sf_dims[3]
无可否认,到目前为止,一切都“运转”得相当低效。我想做的是不让那些sf_x、y、w和h在风中悬挂,因此我也不必从widget函数调用frame函数来获取它们
原因是我觉得它不符合python框架的精神,因为我只想在侧框架上使用网格,而是从窗口小部件函数(首先创建侧框架的点)创建(或使用)网格,我更喜欢只刷新需要刷新的应用程序窗口的子部分,而不是每1秒就扣杀一次
最终发生的是图像每1秒闪烁一次,即使在不需要更新的情况下,图像也会根据应用程序窗口调整大小。我使用Place功能进行此操作,并有效地忽略了side_frame的存在
我目前的尝试有以下几点
fp1_lbl = tk.Label(
master = self.side_frame,
image = fp1
)
fp1_lbl.image = fp1
fp1_lbl.place(
x=sf_x + img_padding,
y=sf_y + 20,
anchor='nw'
)
我得到以下错误的版本:
AttributeError:“应用程序”对象没有“侧框”属性
您需要使用“self”前缀命名对象,以便在其他方法中使用它们。因此,在创建子帧时:
# Section of Application window dedicated to calculations
self.side_frame = tk.Frame(
master = pc_gui,
width = app_width*.25,
height = app_height,
bg = "red"
)
self.side_frame.place(
x = app_width*.75,
y = 0
)
现在,您可以在课堂上的任何地方使用它们,正如您所尝试的:
fp1_lbl = tk.Label(
master = self.side_frame,
image = fp1
)
请记住,名为foo
的变量与self.foo
之间没有隐含关系。他们是两个完全不相关的名字
至于你的尺寸调整,tkinter会帮你的。可以使用relwidth和relheight参数将宽度和高度设置为介于0和1之间的分数。下面是一个演示:
import tkinter as tk
class Application(tk.Frame):
""" GUI """
def __init__(self, pc_gui):
""" Initialize the frame """
tk.Frame.__init__(self, pc_gui)
self.create_frames()
def create_frames(self):
# insert the subframes in *this* Frame (self), not in the master Frame
self.video_frame = tk.Frame(self, bg = "blue")
self.video_frame.place(relheight=1.0, relwidth=.25)
self.side_frame = tk.Frame(self, bg = "red")
self.side_frame.place(relheight=1.0, relwidth=.75, relx=1.0, anchor='ne')
pc_gui = tk.Tk()
pc_gui.geometry("1280x720")
win = Application(pc_gui)
win.pack(fill=tk.BOTH, expand=True)
tk.Button(pc_gui, text = "Don't click me!").pack()
pc_gui.mainloop()
这个答案是完美的,我将其标记为已解决。我忽略了在方法中添加self.*允许在整个类中进行交叉引用这一点。非常感谢。奖励回合:有没有一种方法可以在类之间做同样的事情?鉴于我对self、vs self、vs master等不是100%清楚。当我将tk.Frame(self,bg=“blue”)更改为tk.Frame(pc_gui,bg=“blue”)时,这个解决方案非常有效。当我指定自己而不是PCGUI时,我得到了三帧,红色大约是25%,左边是蓝色,中间是蓝色,而不是75%,右边是灰色。当我为侧框添加relx和锚点时,应用程序将变为灰色。master=self vs master=pc\u gui的真正含义是什么?master在代码中与pc\u gui是同一个对象。自我与胜利是同一个目标。无论您使用什么,结果看起来都一样,这是因为pc_gui和win恰好大小相同。我编辑了我的回复,在根窗口中添加了一个按钮,现在您将看到区别。
import tkinter as tk
class Application(tk.Frame):
""" GUI """
def __init__(self, pc_gui):
""" Initialize the frame """
tk.Frame.__init__(self, pc_gui)
self.create_frames()
def create_frames(self):
# insert the subframes in *this* Frame (self), not in the master Frame
self.video_frame = tk.Frame(self, bg = "blue")
self.video_frame.place(relheight=1.0, relwidth=.25)
self.side_frame = tk.Frame(self, bg = "red")
self.side_frame.place(relheight=1.0, relwidth=.75, relx=1.0, anchor='ne')
pc_gui = tk.Tk()
pc_gui.geometry("1280x720")
win = Application(pc_gui)
win.pack(fill=tk.BOTH, expand=True)
tk.Button(pc_gui, text = "Don't click me!").pack()
pc_gui.mainloop()