Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 在小部件创建自动调整大小(tkinter,python 3)中继承子框架_Python 3.x_Function_Tkinter_Frame_Autosize - Fatal编程技术网

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初始化开始,包括应用程序窗口的起始大小

我想做的是:

  • 分别创建一个主帧(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()