如何使其成为TOO OOP?

时间:2018-07-25 23:26:02

标签: python-3.x function user-interface tkinter

我无法将程序代码制作为OOP。

#-----create the grid--------------------------
i=0
for employee in range(len(Employees)+1):
    for day in range(len(Days)+1):
        self.label = tk.Label(self, relief="ridge", width=13, 
        height=3)
        self.label.grid(row=employee, column=day, )

        if i < len(the_list) and employee>0 and day>0 and employee +                           
                day >=2:
                self.label['text'] = str(the_list[i])
                i += 1

上面的代码是过程性的,并且可以与我想要的输出一起使用。

我的问题是如何通过推送“计算”问题将列表放入网格标签?我不知道如何使用程序中的缩进使其成为OOP。

这是完整的代码

import tkinter as tk


Days= ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday",    
"Saturday", "Sunday"]
the_list = ["North", "Central", "East", "West", "Central", "South",   
"North"]
Employees=["Truck A"]

new_list = {}
labeldays={}
labelemployee={}



class Application():

    def __init__(self, parent):

        self.main_window=parent

        self.top_frame=tk.Frame(self.main_window, bg="PaleGreen2")
        self.top_frame.pack()
        self.bottom_frame=tk.Frame(self.main_window, bg="gray",)
        self.bottom_frame.pack(side="bottom", fill=tk.BOTH)

        self.initUI()


    def initUI(self):


#-----create the grid--------------------------
        i=0
        for employee in range(len(Employees)+1):
            for day in range(len(Days)+1):
                self.label = tk.Label(self, relief="ridge", width=13, 
                height=3)
                self.label.grid(row=employee, column=day, )

                if i < len(the_list) and employee>0 and day>0 and 
                employee + day >=2:
                        self.label['text'] = str(the_list[i])
                        i += 1

#------add in the weekday name labels------------------
        i=1
        for day in Days:
            self.label=tk.Label(self, text=day,  fg="red", bg="snow")
            self.label.grid(row=0, column=i)
            labeldays[day]=self.label
            i +=1

#--------add in name labels on the side--------------
        i=1
        for employee in Employees:
            self.label=tk.Label(self, text=employee,  fg="red",   
            bg="snow")
            self.label.grid(row=i,column=0)
            labelemployee[employee]=self.label
            i +=1

        self.closeButton = tk.Button(self.bottom_frame,    
        text="CALCULATE", command=put_in_the_grid)
        self.closeButton.pack(side=tk.RIGHT, padx=5, pady=5)
        self.okButton = tk.Button(self.bottom_frame, text="QUIT",   
        command=self._destroy)
        self.okButton.pack(side=tk.RIGHT)

    def _destroy(self):
        self.main_window.destroy()


def main():

    root = tk.Tk()
    root.title("class basic window")
    root.geometry("1000x300")
    root.config(background="LightBlue4")
    app = Application(root)
    root.mainloop()

if __name__ == '__main__':
    main()

我要这样做的原因是因为我创建了一个按钮,该按钮将使用列表的值并将其放入我创建的网格标签中。该按钮将执行“ def put_in_the_grid(self):”,并保留网格标签。 enter image description here我不知道是继承问题还是“自我”问题。如果是的话,我缺少的“自我”论点在哪里。

我也对这个想法感到困惑,因为在程序中有缩进,OOP也应该缩进吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我们在您的代码中有几个问题要解决。

转换为OOP并使用类是一个好主意,但是您需要了解如何设置类。

您正在尝试创建一个类对象,但是该对象没有继承任何tkinter方法,这就是为什么您收到注释中提到的'Application' object has no attribute 'tk'.错误的原因。我们需要告诉该类它是从tk方法继承的,并完成该方法的 init 部分。

在这种情况下,我们可以使类继承自Tk()并从那里运行我们的应用程序。

class Application(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)

接下来,您需要设置所有初始窗口布局。这是在def __init__(self):部分中完成的,您无需运行第二个init方法即可完成所有设置。在本节中,我们可以放置代码所需的所有类属性。在这种情况下,我还添加了全局列表和字典作为类属性,因为随着代码的进行,看起来可能再次需要它们。

我们要解决的下一个问题是在self.label循环中使用for。这不是必需的,只是多余的代码。相反,您可以将标签直接分配给字典,然后在该字典键/值上使用网格。因为我们将您的字典移至类中并将其设置为属性,所以我们需要确保使用self.前缀,以便代码可以找到该字典。其他循环也是如此。

#------add in the weekday name labels------------------
        i=1
        for day in self.days:
            self.label_days[day]=tk.Label(self.top_frame, text=day,  fg="red", bg="snow")
            self.label_days[day].grid(row=0, column=i)
            i +=1

我留下的最后一点是100%不需要的。

您的最后一个按钮QUIT不需要链接到方法,可以在此处简单地使用command=self.destroy的命令,它将按需工作。就是说,我保留方法def _destroy(self):完整无缺,以表明您的方法可以在其余代码之后编写,因为我们使用的是一个类,并且该类可以补偿,这与在需要函数编写的类之外执行此操作不同在调用它的代码之前。

这里是最后一个示例,应该是更清晰的PEP8可行代码段。 PEP8是指格式化。我将代码简化为更易于阅读的代码,并修复了变量名的格式。

import tkinter as tk


class Application(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.title("class basic window")
        self.geometry("1000x300")
        self.config(background="LightBlue4")

        self.top_frame = tk.Frame(self, bg="PaleGreen2")
        self.top_frame.grid(row=0, column=0)
        self.bottom_frame = tk.Frame(self, bg="gray")
        self.bottom_frame.grid(row=1, column=0)

        self.days= ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
        self.the_list = ["North", "Central", "East", "West", "Central", "South", "North"]
        self.employees=["Truck A"]
        self.label_days = {}
        self.label_employee = {}
#-----create the grid--------------------------
        i=0
        for employee in range(len(self.employees)+1):
            for day in range(len(self.days)+1):
                label = tk.Label(self.top_frame, relief="ridge", width=13, height=3)
                label.grid(row=employee, column=day, )

                if i < len(self.the_list) and employee > 0 and day > 0 and employee + day >= 2:
                        label['text'] = str(self.the_list[i])
                        i += 1
#------add in the weekday name labels------------------
        i=1
        for day in self.days:
            self.label_days[day]=tk.Label(self.top_frame, text=day,  fg="red", bg="snow")
            self.label_days[day].grid(row=0, column=i)
            i +=1
#--------add in name labels on the side--------------
        i=1
        for employee in self.dmployees:
            self.label_employee[employee]=tk.Label(self.top_frame, text=employee,  fg="red", bg="snow")
            self.label_employee[employee].grid(row=i,column=0)
            i +=1

        tk.Button(self.bottom_frame, text="CALCULATE").grid(row=0, column=0)
        tk.Button(self.bottom_frame, text="QUIT", command=self._destroy).grid(row=1, column=0)

    def _destroy(self):
        self.destroy()


if __name__ == '__main__':
    app = Application()
    app.mainloop()