如何解决在小部件创建自动调整大小中继承子帧tkinter,python 3
我想做的是:
- 分别创建一个主框架(pc_gui)和两个子框架(video_frame)和(side_frame)。
- 允许用户调整应用程序窗口的大小以适应并调整所有框架,小部件,图像等的大小。
- gui中其他地方的参考框架。
为了使事情保持整洁(可能出错),我有一个Application类以及一些函数:init,app_size,create_frames,create_widgets和一个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()
这是app_size函数。目的是解析应用程序窗口和显示监视器的当前大小,并假定用户将在程序运行时对其进行更改以适应需要。
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,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框架的正确精神,因为我只想在侧框架上使用Grid,而是从小部件函数创建(或使用)Grid(在排名第一),而我宁愿只刷新需要刷新的应用程序窗口的子部分,而不是每1秒刷新一次。
最终发生的是图像每1秒钟闪烁一次,即使什么都不需要更新,并且图像根据应用程序窗口的大小进行调整时,我仍使用Place功能执行此操作,而实际上忽略了side_frame的存在。 / p>
我目前的尝试是围绕以下
fp1_lbl = tk.Label(
master = self.side_frame,image = fp1
)
fp1_lbl.image = fp1
fp1_lbl.place(
x=sf_x + img_padding,anchor='nw'
)
我得到以下错误的版本:
AttributeError:“应用程序”对象没有属性“ 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
)
现在,您可以尝试在班级中的任何地方使用它们:
fp1_lbl = tk.Label(
master = self.side_frame,image = fp1
)
请记住,名为foo
和self.foo
的变量之间没有隐含的关系。它们是2个完全不相关的名称。
对于调整大小,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()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。