微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在小部件创建自动调整大小中继承子帧tkinter,python 3

如何解决在小部件创建自动调整大小中继承子帧tkinter,python 3

我想做的是:

  1. 分别创建一个主框架(pc_gui)和两个子框架(video_frame)和(side_frame)。
  2. 允许用户调整应用程序窗口的大小以适应并调整所有框架,小部件,图像等的大小。
  3. 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
    )

请记住,名为fooself.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 举报,一经查实,本站将立刻删除。