【问题标题】:How to place widgets into different frames in Tkinter, using OOP如何使用 OOP 在 Tkinter 中将小部件放置到不同的框架中
【发布时间】:2013-01-29 16:16:28
【问题描述】:

背景

大家好!我目前正在开发一个可以加载和保存文本文件的基本 GUI 文本编辑器。我想为工具栏和文本框使用多个框架,因为我学习了here. 我正在使用 OOP,并在__init__ 方法中设置了我的框架,在widget 方法中设置了小部件。由于某种原因,小部件无法放置在它们各自的框架中。

代码

from Tkinter import *
class Application:
    def __init__(self,parent):  #initialize the grid and widgets
        self.myParent = parent

        #Init the toolbar
        self.toolbar = Frame(parent)
        self.toolbar.grid(row = 0)

        #Init frame for the text box

        self.mainframe = Frame(parent)
        self.toolbar.grid(row = 1)
    def widget(self):#Place widgets here

        #Save Button
        self.saveButton = Button (self, self.toolbar,
                                  text = "Save", command = self.saveMe)
        self.saveButton.grid(column = 0, row = 0, sticky = W)

        #Open Button
        self.openButton = Button (self, self.toolbar,
                                 text = "Open", command = self.openMe)
        self.openButton.grid(column = 0, row = 1, sticky = W)
        #Area where you write 
        self.text = Text (self, self.mainframe,
                          width = (root.winfo_screenwidth() - 20),
                          height = (root.winfo_screenheight() - 10))
       self.text.grid(row = 2)

问题

  1. 仍然使用不同的方法,如何确保每个小部件都放置在正确的框架中?

    • 如果这是不可能的,请告诉我如何使用 OOP 来实现 - 我对 Tkinter 的这种设置感到最满意,并承诺自己会改进。
  2. 解释你的答案。我需要同源 - 而不是简单地对着电脑点头并继续前进。

  3. 额外功劳:如何在 OOP 中使用 Tkinter 初始化多个窗口(每个窗口是不同的类)?例如,如果这是我的代码:

    class MainWindow(Frame):
        ---init stuff---
        def widget(self):
            newWindow = Button(self, text = "click for a new window",
                               command = self.window)
            newWindow.grid()
       def window(self):
             #What would I put in here to initialize the new window??
    
    class theNextWindow(Frame):
    

    我会在window.self 方法中添加什么以使theNextWindow 窗口可见?

感谢大家的帮助!

编辑 1

我在__init__ 方法中添加了self.widget() 行,我得到了这个“奇妙”错误的回报:

Traceback (most recent call last):
File "D:\Python Programs\Text Editor\MyTextv2.py", line 67, in <module>
 app = Application(root)
File "D:\Python Programs\Text Editor\MyTextv2.py", line 14, in __init__
 self.widget()
File "D:\Python Programs\Text Editor\MyTextv2.py", line 24, in widget
 text = "Save", command = self.saveMe)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 2044, in __init__
 Widget.__init__(self, master, 'button', cnf, kw)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1965, in __init__
 BaseWidget._setup(self, master, cnf)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1943, in _setup
 self.tk = master.tk
AttributeError: Application instance has no attribute 'tk'

由于错误日志在这里清楚地引用了我的主循环:File "D:\Python Programs\Text Editor\MyTextv2.py", line 67, in <module> app = Application(root) 我决定添加它:

root = Tk()
root.title("My Text Editor")

#This is wierd - it gets the computer windows dimensions
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(0)

#And then applies them here
root.geometry("%dx%d+0+0" % (w, h))

app = Application(root)

root.mainloop()

【问题讨论】:

  • 你现在拥有的有什么问题?如果代码产生错误,请在您的问题中包含错误文本。此外,就风格而言,widget 不是一个很好的方法名称。方法 do 的事情,一个好的方法名称表明该方法做什么。 widget() 的更好名称是 setUpWidgets()setUpWindow()
  • 代码没有产生错误,是逻辑问题。窗口只是空的和灰色的 - 显然不是很有帮助!
  • 在您的代码中,您永远不会调用.widget(),因此该方法中的任何代码都不会被执行。运行所有这些东西的代码在哪里?
  • @JoelCornett 感谢您的建议。我添加了它,然后我收到了一个很好的错误消息......另外,你为什么认为widget() 不是一个好名字? PS:这是一个 n00b 问题:我如何在 Windows 7 上进行代码引用?

标签: python python-2.7 tkinter


【解决方案1】:

问题一:

一个小部件只能有一个直接父级。传递两个父母没有语法。例如,您似乎将selfself.toolbar 作为self.saveButton 的父母传递。

myButton = Button(self.toolbar, text="Blah", command=self.someCommand)

是你应该使用的形式。

问题 2:

假设您希望将Application(也称为Button(self, self.toolbar...) 中的self)作为myButton 的父级。这也不起作用,因为为了成为 Tk 小部件的分层父级,类也必须是 Widget 的实例。通常,如果你想要这样做,你会做的是在Application 中继承tk.Tk(),如下所示:

class Application(Tk):

    def __init__(self, *args, **kwargs):


        Tk.__init__(self, *args, **kwargs) #It's important that you call the parent class's __init__ method first

        self.createWidgets()

    def createWidgets(self):

        self.myButton = Button(self, text="Blah", command=lambda x: print "x")
        #this is ok, because now self (AKA Application) is a valid instance of Tk

【讨论】:

    【解决方案2】:

    终于找到了答案。根据我的发现(如果错误,请随时编辑),在 Tkinter 中只有两种方法可以继承 Frame:从类本身和从小部件当前所在的方法。解决这个问题,我将类Application 设置为一个框架,然后在其中放置其他框架。这是我所做的基本再现:

    #Import Tkinter
    from Tkinter import *
    
    #Main Frame
    class Application(Frame):
        def __init__(self, master):  #initialize the grid and widgets
            Frame.__init__(self,master)
            self.grid()
            self.redFUN() #initialize the red frame's Function
            self.greenFUN() #initialize the green frame's Function
            self.widgets() #To show that you can still place non-Frame widgets 
        def widgets(self):
            self.mylabel = Label (self, text = "Hello World!")
            self.mylabel.grid()
        def redFUN(self): #The 'self' means that it is an instance of the main frame
            #Init the red frame
            self.redFrame = Frame(root, width = 100, height = 50,pady = 5,
                                  bg = "red")
            self.redFrame.grid()
    
    
    
        def greenFUN(self): #Child of the mainframe
            self.greenFrame = Frame(root, width = 100, height = 50,pady = 5,
                              bg = "green") #it is green!
            self.greenFrame.grid()
    
    
    
    
    
    
    
    
    #These lines of code are used for the grid
    root = Tk()
    root.title("Frame Example")
    root.geometry("300x300")
    app = Application(root)
    
    root.mainloop()
    

    我希望这对每个人都有帮助 - 如果您有任何问题,请随时发表评论!

    【讨论】:

    • 您在评论中写道#The 'self' means that it is the child of the main frame。这是不正确的。 self 表示它是一个实例方法——一个属于类的实例而不是类的方法。 “孩子”一词不适用于这种情况。
    • 这里有什么错误信息吗? -1 的原因是什么?
    • 投反对票时,请解释原因并提出改进的理由。
    猜你喜欢
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多