在小部件创建中继承子框架自动调整大小(tkinter,python 3)
Inherit subframes in widget creation auto sizing (tkinter, python 3)
我想做的是:
- 分别创建一个主框架(pc_gui)和两个子框架(video_frame)和(side_frame)
- 允许用户能够调整应用程序的大小 window 以适应所有框架、小部件、图像等相应地调整大小。
- GUI 中其他地方的参考框架。
为了保持整洁,可能会出错,我有一个应用程序 class,以及函数:init、app_size、create_frames、create_widgets , 和一个更新函数。还有很多,但如果我能让这个核心部分正常工作,我应该能够继续取得进步。
这从相对标准的 tkinter UI 初始化开始,其中包括应用程序的起始大小 window。
# 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()
然后创建 class 主框架 (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()
这是app_size函数。它的目的是解析应用程序的当前大小 window 和显示监视器假设用户将更改这些以适应程序 运行.
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_size 值创建子帧。这些颜色只是为了帮助我在开发过程中跟踪事物。
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]
...
fp1_lbl = tk.Label(
master = pc_gui,
image = fp1
)
fp1_lbl.image = fp1
fp1_lbl.place(
x=sf_x + img_padding,
y=sf_y + 20,
anchor='nw'
)
诚然,到目前为止,一切都“有效”,但效率很低。我想做的是不让那些 sf_x、_y、_w 和 _h 挂在风中,因此我也不必从小部件函数调用 frame 函数来获取它们.
原因是我觉得它不符合 python 框架的正确精神,因为我只想在侧框架上使用网格,而是从小部件功能创建(或使用)网格(重点首先创建 side_frame),我宁愿只刷新应用程序 window 需要刷新的子部分,而不是每 1 秒刷新一次。
最终发生的是图像每 1 秒闪烁一次,即使没有任何内容需要更新并且图像会根据应用程序调整大小 window 我正在使用 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: 'Application' object has no attribute 'side_frame'
您需要使用“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
)
现在您可以在 class 中的任何地方使用它们,正如您已经尝试过的那样:
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()
我想做的是:
- 分别创建一个主框架(pc_gui)和两个子框架(video_frame)和(side_frame)
- 允许用户能够调整应用程序的大小 window 以适应所有框架、小部件、图像等相应地调整大小。
- GUI 中其他地方的参考框架。
为了保持整洁,可能会出错,我有一个应用程序 class,以及函数:init、app_size、create_frames、create_widgets , 和一个更新函数。还有很多,但如果我能让这个核心部分正常工作,我应该能够继续取得进步。
这从相对标准的 tkinter UI 初始化开始,其中包括应用程序的起始大小 window。
# 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()
然后创建 class 主框架 (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()
这是app_size函数。它的目的是解析应用程序的当前大小 window 和显示监视器假设用户将更改这些以适应程序 运行.
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_size 值创建子帧。这些颜色只是为了帮助我在开发过程中跟踪事物。
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]
...
fp1_lbl = tk.Label(
master = pc_gui,
image = fp1
)
fp1_lbl.image = fp1
fp1_lbl.place(
x=sf_x + img_padding,
y=sf_y + 20,
anchor='nw'
)
诚然,到目前为止,一切都“有效”,但效率很低。我想做的是不让那些 sf_x、_y、_w 和 _h 挂在风中,因此我也不必从小部件函数调用 frame 函数来获取它们.
原因是我觉得它不符合 python 框架的正确精神,因为我只想在侧框架上使用网格,而是从小部件功能创建(或使用)网格(重点首先创建 side_frame),我宁愿只刷新应用程序 window 需要刷新的子部分,而不是每 1 秒刷新一次。
最终发生的是图像每 1 秒闪烁一次,即使没有任何内容需要更新并且图像会根据应用程序调整大小 window 我正在使用 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: 'Application' object has no attribute 'side_frame'
您需要使用“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
)
现在您可以在 class 中的任何地方使用它们,正如您已经尝试过的那样:
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()