为什么要在类中放置框架和小部件? [英] Why put frames and widgets in classes?

查看:82
本文介绍了为什么要在类中放置框架和小部件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如问题所指出的那样,我似乎无法完全掌握使用tkinter使用类的意义。



我已经阅读了很多不同的站点,但我一直在获取有关如何创建和使用类的搜索结果,但是到目前为止,还没有任何内容可以帮助我。在询问这一问题时,我什至还仔细研究了建议的问题。我最了解的是布莱恩(Bryan)在此问题



但是,我仍然觉得自己快到了



在链接中的示例中,他创建了一个非常规程序,然后创建了一个更好,更常规的程序来执行一样。我知道它所代表的规模要比真正受益于面向对象方法的数千行程序要小得多。



每个小部件都需要单独存放吗?



类是否可以使用创建和放置框架的方法?另外,那些相同的类是否可以具有比可以在先前制作的框架中创建,修改和放置小部件的方法更多的方法?



我也有一些代码可以让我创建,修改和放置小部件。尽管我知道这不是常规做法,所以我也将不胜感激。

 将tkinter导入为tk 
$ b $,对此代码有何建议?

  b def布局(自身,行= 0,列= 0,列跨度=无,行权重=无,列权重=无,颜色=无,粘滞=无,ipadx =无,padx =无,ipady =无,pady =无) :
self.grid(行=行,列=列,columnpan =列跨度,粘性=粘性,ipadx = ipadx,padx = padx,ipady = ipady,pady = pady) ,weight = row_weight)
self.grid_columnconfigure(column,weight = column_weight)
self.config(bg = color)

class MyLabels(tk.Label):
def __init __(自己,父母,文本,** kwargs):
tk.Label .__ init __(自己,父母,文本=文本)
layout(self,** kwargs)

类MyButtons(tk.Button):
def __init __(自身,父代,文本,命令,** kwargs):
tk.Button .__ init __(自身,父代,文本=文本,命令= command)
layout(self,** kwargs)


window = tk.Tk()
test_button = MyButtons(窗口, hi,无,color = pink)
window.mainloop()






评论后编辑:
自昨天以来,我已经工作了很多小时,试图结合您对我的想法。这就是我想出的:

 将tkinter导入为tk 

window = tk.Tk( )

类MyWidgets(tk.Frame):
def __init __(自己,父母):
tk.Frame .__ init __(自己,父母)
self.layout ()

def layout(self):
self.grid(row = 0,column = 0)
self.config(bg = blue)

class MyButtons(MyWidgets):
def __init __(self,parent,text):
MyWidgets .__ init __(self,parent)
tk.Button(parent,text = text)
self.layout()

frme = MyWidgets(窗口)
btn = MyButtons(frme,text = Test)
window.mainloop()

在这个小小的副程序中,我尝试过移动并重写很多区域,即使我能够证明 btn 实际上是在访问 self.config(bg = blue)属性,按钮不会似乎没有改变。事实上,我无法找到一种方法来创建按钮,而不必在创建按钮后立即将 self.grid()放入子类中。



尽管如此,即使我确实添加了 self.grid(),按钮仍然不会变成蓝色。



为什么

为什么子类创建按钮时按钮不会出现,



注意:我故意省略了整个 layout函数,而只用了一个简单的配置方法。我认为,如果我能理解这一点,便可以找到一种将整个函数重新整合到代码中的方法。

解决方案


每个小部件是否都需要位于单独的框架中,而这可能是更大框架的一部分?


有点像问数学表达式的每个部分是否都需要括号。严格来说,答案是否。但是,使用框架组织小部件组是一种工具,旨在简化编写和理解代码的过程,就像复杂数学方程式中的括号使编写和理解方程式更加容易。


类是否可以使用创建和放置框架的方法?另外,那些相同的类是否可以具有比在先前制作的框架中创建,修改和放置小部件的方法更多的方法?


是的,是的。类中的方法对其可以做什么和不可以做什么没有任何限制。类的方法可以执行普通函数可以执行的任何操作。


我还有一些代码可以让我创建,修改和放置小部件。尽管我知道这不是常规做法,所以我也将不胜感激。关于如何使用此代码使其变得更好的任何建议?


更好是非常主观的。对于20行代码而言,更好的选择对于200、2,000或20,000可能不会更好。对于仅使用两次的功能而言,更好的方法可能对于使用数百或数千次的功能却未必更好(反之亦然)。



也就是说,做了一件非常不常规的事情,这会使您的代码更难理解:您正在使用 self 作为不是类方法的函数的参数。 self 表示某些特定于python程序员的东西;在方法的上下文之外使用它非常令人困惑。



对于方法 layout ,您应该做以下两件事之一:




  • self 重命名为 widget 自我

  • 创建定义布局的基类,然后创建您的类从基类继承。在这种情况下, self 是正确的第一个参数。






答案的这一部分是指我编写原始答案后添加的代码。



我所指的基类需要成为一个单独的班级。例如:

  class Base():
def layout(self):
self.grid( row = 0,column = 0)
self.config(bg = blue)

class MyLabels(Base,tk.Label):
def __init __(self,parent ,text,** kwargs):
tk.Label .__ init __(self,parent,text = text)
self.layout(self,** kwargs)

class MyButtons (Base,tk.Button):
def __init __(self,parent,text,command,** kwargs):
tk.Button .__ init __(self,parent,text = text,command = command)
self.layout(self,** kwargs)

此类有时被称为 mixin ,因为它并非旨在实例化为独立对象。而是,它混合了其他类的一些其他行为。 mixin通常具有方法,但不会具有自己的 __ init __


As the question states, I can't seem to fully grasp the point of using classes with tkinter.

I have read through a decent number of different sites but I keep getting search results on how to create and use classes, but none so far have been able to get through to me. I've even scoured through the suggested questions while asking this one. The closest I've come to understanding is Bryan's explanation on this answer to the question Why use classes when programming a tkinter gui?

But still, I feel like I'm almost there, just not quite over the edge of understanding.

In his example in the link, he creates an unconventional program, and then a better, more conventional program that does the same thing. I know that it represents a much smaller scale than the thousand-line programs that could really benefit from an object oriented approach.

Does every widget need to be in its own separate frame that's maybe part of an even bigger frame?

Can classes have methods that create and place a frame? In addition, can those same classes have methods than can create, modify, and place a widget within the previously made frame?

I also have some code that allows me to create, modify, and place a widget. Although I know it's not conventional, so I would greatly appreciate some input on this as well. Any suggestions on what you would do with this code to make it better?

import tkinter as tk

def layout(self, row=0, column=0, columnspan=None, row_weight=None, column_weight=None, color=None, sticky=None, ipadx=None, padx=None, ipady=None, pady=None):
    self.grid(row=row, column=column, columnspan=columnspan, sticky=sticky, ipadx=ipadx, padx=padx, ipady=ipady, pady=pady)
    self.grid_rowconfigure(row, weight=row_weight)
    self.grid_columnconfigure(column, weight=column_weight)
    self.config(bg=color)

class MyLabels(tk.Label):
    def __init__(self, parent, text, **kwargs):
        tk.Label.__init__(self, parent, text=text)
        layout(self, **kwargs)

class MyButtons(tk.Button):
    def __init__(self, parent, text, command, **kwargs):
        tk.Button.__init__(self, parent, text=text, command=command)
        layout(self, **kwargs)


window = tk.Tk()
test_button = MyButtons(window, "hi", None, color="pink")
window.mainloop()


Edited after comments: So I've been working many hours since yesterday trying to incorporate the ideas you've had for me. This is what I came up with:

import tkinter as tk

window = tk.Tk()

class MyWidgets(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.layout()

    def layout(self):
        self.grid(row=0, column=0)
        self.config(bg="blue")

class MyButtons(MyWidgets):
    def __init__(self, parent, text):
        MyWidgets.__init__(self, parent)
        tk.Button(parent, text=text)
        self.layout()

frme = MyWidgets(window)
btn = MyButtons(frme, text="Test")
window.mainloop()

I've tried moving things around and rewriting lots of areas on this little side program, and even though I was able to prove that btn is infact accessing the self.config(bg="blue") attribute, the button doesn't appear to change. As a matter of fact I can't find a way to make the button appear without needing to put self.grid() in the child class just after the button is created.

Still, even if I did add the self.grid() the button still won't turn blue. Is it something with self?

Why won't the button appear when the child class creates it, and the parent class places it?

Note: I've purposefully omitted the entire layout function and replaced it with just a simple config method. I figure if I can understand this, I can then find a way to incorporate the whole function back into the code.

解决方案

Does every widget need to be in its own separate frame that's maybe part of an even bigger frame?

That's a bit like asking if every part of a mathematical expression needs parenthesis. Strictly speaking, the answer is "no". However, using frames to organize groups of widgets is a tool designed to make writing and understanding the code easier, much like parenthesis in a complex math equation makes writing and understanding the equation easier.

Can classes have methods that create and place a frame? In addition, can those same classes have methods than can create, modify, and place a widget within the previously made frame?

Yes, and yes. Methods in a class don't have any limitations on what they can and cannot do. Methods of a class can do anything that a normal function can do.

I also have some code that allows me to create, modify, and place a widget. Although I know it's not conventional, so I would greatly appreciate some input on this as well. Any suggestions on what you would do with this code to make it better?

"Better" is highly subjective. What is better for 20 lines of code might not be better for 200, 2,000, or 20,000. What is better for a function used exactly twice might not be better for a function used hundreds or thousands of times (or visa versa).

That being said, you're doing one thing that is very unconventional and which leads to making your code harder to understand: you're using self as a parameter for a function that is not a method of a class. self means something very specific to python programmers; using it outside of the context of a method is very confusing.

You should do one of two things for the method layout:

  • Rename self to be widget or any other term other than self
  • Create a base class that defines layout, and then have your classes inherit from the base class. In that case, self is the proper first argument.

This part of the answer refers to code which was added after I wrote my original answer.

The base class I was referring to needs to be a separate class. For example:

class Base():
    def layout(self):
        self.grid(row=0, column=0)
        self.config(bg="blue")

class MyLabels(Base, tk.Label):
    def __init__(self, parent, text, **kwargs):
        tk.Label.__init__(self, parent, text=text)
        self.layout(self, **kwargs)

class MyButtons(Base, tk.Button):
    def __init__(self, parent, text, command, **kwargs):
        tk.Button.__init__(self, parent, text=text, command=command)
        self.layout(self, **kwargs)

This type of class is sometimes called a mixin because it's not designed to be instantiated as a standalone object. Rather, it "mixes in" some additional behavior to other classes. A mixin will typically have methods, but won't have its own __init__.

这篇关于为什么要在类中放置框架和小部件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆