我是Stack Overflow的新成员。我找到了这个帖子,但不允许对它发表评论或提问,所以我想我应该在这里引用它:How can I make a in interactive list in Python's Tkinter complete with buttons that can edit those listings?
from tkinter import *
import os
import easygui as eg
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
# character box
Label(frame, text = "Characters Editor").grid(row = 0, column = 0, rowspan = 1, columnspan = 2)
charbox = Listbox(frame)
for chars in []:
charbox.insert(END, chars)
charbox.grid(row = 1, column = 0, rowspan = 5)
charadd = Button(frame, text = " Add ", command = self.addchar).grid(row = 1, column = 1)
charremove = Button(frame, text = "Remove", command = self.removechar).grid(row = 2, column = 1)
charedit = Button(frame, text = " Edit ", command = self.editchar).grid(row = 3, column = 1)
def addchar(self):
print("not implemented yet")
def removechar(self):
print("not implemented yet")
def editchar(self):
print("not implemented yet")
root = Tk()
root.wm_title("IA Development Kit")
app = App(root)
root.mainloop()谁能给我解释一下为什么最后一行是root.mainloop()?作为Python的新手,并且来自面向过程的背景,没有面向对象的经验,我会认为它应该是app.mainloop()。
事实上,app = App(root),在剩下的代码中再也不会使用app了!我很难理解为什么root.mainloop()仍然有效。
发布于 2014-03-28 05:11:51
我不确定您是否会对这个答案感到满意,但是您可以调用root.mainloop(),因为root是具有mainloop方法的对象。在您给出的代码中,App没有mainloop函数。
简单地说,这就是tkinter的工作方式--您总是通过调用根窗口的mainloop方法来结束脚本。当该方法返回时,您的程序将退出。
让我们从头开始。最简单的、非面向对象的Tkinter程序将如下例所示。请注意,这是一个python2.x示例,我没有使用全局导入,因为我认为全局导入是不好的。
import Tkinter as tk
root = tk.Tk()
<your widgets go here>
root.mainloop()许多人发现纯过程风格并不是编写代码的有效方式,因此他们可能会选择以面向对象的风格编写代码。将“应用程序”视为单例对象是很自然的。有很多方法可以做到这一点--不幸的是,你问题中的一种方法并不是一种更清晰的方法。
一种稍微好一点的方法,IMO,是这样构造代码:
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
<your widgets go here>
app = App()
app.mainloop()在本例中,mainloop仍然被调用,尽管现在它是App的方法,因为App继承自Tk。它在概念上与root.mainloop()相同,因为在本例中,app是根窗口,尽管它使用了不同的名称。
因此,在这两种情况下,mainloop都是属于根窗口的方法。在这两种情况下,都必须调用它才能使GUI正常工作。
还有第三个变体,就是您选择的代码正在使用的代码。对于这个变体,有几种方法可以实现它。不同的是,您的问题使用一个类来定义图形用户界面,但不是从Tk继承的。这是非常好的,但是您仍然必须在某些时候调用mainloop。由于您没有在类中创建(或继承) mainloop函数,因此必须调用与根窗口关联的函数。我提到的变化是如何以及在何处将App实例添加到根窗口,以及mainloop最终是如何调用的。
就我个人而言,我更喜欢App继承自Frame,并将应用程序打包到应用程序定义之外。我使用的模板如下所示:
class App(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
<your widgets go here>
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
app.pack(fill="both", expand=True)
root.mainloop()在最后一个示例中,app和root是两个完全不同的对象。app表示存在于根窗口内的框架。框架通常以这种方式使用,作为其他小部件组的容器。
因此,在所有情况下,都必须调用mainloop。它在哪里被调用,以及如何调用,这有点取决于你的编码风格。有些人喜欢从根窗口继承,有些人不喜欢。在这两种情况下,你都必须调用根窗口的mainloop函数。
发布于 2017-07-29 18:54:41
我测试了这两个,就像你看到的:
一种是用"app.“+ ".pack()"编写的,另一种是用"mainframe.”+ ".grid()"编写的。
#-*- coding: utf-8 -*-
#THIS IS THE "MAINFRAME." - PART
from Tkinter import *
import ttk
def show():
p = password.get() #get password from entry
print(p)
root = Tk()
root.title("Ingos first program")
mainframe = ttk.Frame(root, padding="30 30 60 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
password = StringVar() #Password variable
passEntry = Entry(mainframe, textvariable=password, show='*').grid(column=3, row=3, sticky=S)
submit = Button(mainframe, text='Show Console',command=show).grid(column=3, row=4, sticky=S)
root.mainloop()
def show():
p = password.get() #get password from entry
print(p)
#THIS IS THE "APP."-PART. BOTH WORKS FINE.
app = Tk()
app.title("Ingos first program")
password = StringVar() #Password variable
passEntry = Entry(app, textvariable=password, show='#').pack()
submit = Button(app, text='Show Console',command=show).pack()
app.mainloop()这个实例在python2.7上运行得很好。在测试中,甚至连应用程序也是如此。可以处理"mainloop()“的那段脚本打开两个窗口,一个接一个(如果你关闭第一个)并且第一个程序是格式化的,没有尝试写colum=3...pack()夹子里的东西。
我还是开始了Tkinter,所以别和我争,只是试着..希望我能帮助你回答你的问题。万事如意,英戈
发布于 2014-03-28 05:03:15
App对象只是您的应用程序代码,您调用App(root)的原因是使用您的类创建一个实例,然后该类可以访问您的根窗口。
它在__init__方法中接收此引用:
def __init__(self, master):
# master refers to the root window now
...您可以看到App对象的完整定义(由以class App:开头的代码块给出),而且它甚至没有mainloop方法,因此要启动主Tkinter循环,您必须在根窗口上调用它。
在example in the Python2 documentation中,它们确实会像您怀疑的那样调用它,但请注意,它们的示例类是Tk object Frame的子类。在您的示例代码中,App是一个不继承任何内容的老式类。
https://stackoverflow.com/questions/22698980
复制相似问题