Python Tk/Tkinter中的事件流故障
我正在使用Python3.1和Tk将一些东西组合起来 我想循环使用我在这里定义的“NewDataFrame”对象的不同方法:Python Tk/Tkinter中的事件流故障,python,tkinter,wait,tk,Python,Tkinter,Wait,Tk,我正在使用Python3.1和Tk将一些东西组合起来 我想循环使用我在这里定义的“NewDataFrame”对象的不同方法: from tkinter import * from tkinter import ttk import string root = Tk() mainframe = ttk.Frame(root) mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) mainframe.columnconfigure(0, wei
from tkinter import *
from tkinter import ttk
import string
root = Tk()
mainframe = ttk.Frame(root)
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
value = StringVar()
dataname = StringVar()
class MenuFrame:
def __init__(self, parent):
self.myParent = parent
self.menuFrame = ttk.Frame(self.myParent)
self.newButton = ttk.Button(self.myParent, text="new dataset", command=self.newClick)
self.loadButton = ttk.Button(self.myParent, text="load dataset", command=self.loadClick)
self.menuFrame.grid(column=0, row=0)
self.newButton.grid()
self.loadButton.grid()
def newClick(self):
self.instructions = ttk.Label(self.menuFrame, text="enter a name for your new dataset")
self.instructions.grid()
self.nameEntry = ttk.Entry(self.menuFrame, textvariable=dataname)
self.enterName = ttk.Button(self.menuFrame, text="enter", command=self.newData)
self.nameEntry.grid()
self.enterName.grid()
类NewDataFrame:
def __init__(self, parent, dataname):
self.myParent = parent
self.newDataFrame = ttk.Frame(parent)
self.dataSet = DataSet(dataname)
self.instructions = ttk.Label(self.newDataFrame)
self.instructions.configure(text="enter aspects of %s, separated by commas" % (self.dataSet.getName()))
self.enterBar = ttk.Entry(self.newDataFrame, textvariable=value)
self.enterButton = ttk.Button(self.newDataFrame, text="ENTER", command=self.enterClick)
self.doneButton = ttk.Button(parent, text="DONE", command=self.createAspects)
self.newDataFrame.grid()
self.enterBar.grid()
self.goingOn.grid()
self.instructions.grid()
self.enterButton.grid()
self.doneButton.grid()
我希望doneButton循环使用几个不同的命令,正如您在newDataSet框架的这些方法中看到的:
def createAspects(self):
for asp in (value.get().split(',')):
aspect = Aspect(self.dataSet.getName(), asp)
self.dataSet.addAspect(aspect)
for a in self.dataSet.getAspects():
self.createFile(i=a.getName())
self.instructions.configure(text="enter groups of %s, separated by commas" % (a.getName()))
self.doneButton.configure(command=self.createGroups(aspect=a))
def createGroups(self, aspect=""):
for gro in (value.get().split(',')):
print(gro)
group = Group(self.dataSet.getName(), aspect.getName(), gro)
aspect.addGroup(group)
for group in aspect.getGroups():
self.createFile(i=aspect.getName(), j=group.getName())
self.instructions.configure(text="enter members of %s, separated by commas" % (group.getName()))
self.doneButton.configure(command=self.createMembers(aspect=aspect, group=group))
def createMembers(self, aspect="", group=""):
for mem in (value.get().split(',')):
member = Member(self.dataSet.getName(), aspect.getName(), group.getName(), mem)
group.addMember(member)
for mem in group.getMembers():
self.createFile(i=aspect.getName(), j=group.getName(), k=mem.getName())
menuFrame = MenuFrame(mainframe)
root.mainloop()
我是个大傻瓜,但这需要我做很多工作,我真的被困在原地,所以我需要一些创造性的投入。我希望此程序暂停帧,并允许用户在值变量中为以下每种对象类型输入内容:方面,将包含组,将包含成员(按树形图组织)
目前,程序不会在createGroup执行级别等待(我希望它会等待再次单击以继续执行createMember部分),而是要求用户在输入方面后立即输入成员
我希望这不是太抽象,非常感谢所有试图提供帮助的人。让我们从主要错误开始:
self.doneButton.configure(command=self.createGroups(aspect=a))
当Python到达这一行时,它计算self.createGroups(aspect=a)并将返回值传递给命令
。
因此,self.createGroups(aspect=a)
最终被调用。相反,您确实希望将回调函数传递给命令
,以便稍后调用(当按下next中的done
按钮时)
试图通过重新配置done
回调来管理控制流会带来麻烦。我们不仅要创建已经绑定了正确参数(例如,aspect=a
)的函数,这样我们就有了一个需要零参数的函数,就像done回调所期望的那样,而且(更困难的是)我们还必须识别何时从createMembers到createGroups重置done
回调,回到CreateSpect。我们将对控制流程进行微观管理
如果我们能让Python来处理这些细节,那不是很好吗
您正在寻找的是一个可以调用、暂停、稍后返回并在先前暂停的位置恢复的函数。
Python正好有这样一种函数——a
比如说,
def gen():
for i in range(5):
print(i)
yield
mygen = gen().next
mygen()
mygen()
屈服
0
1
请注意,每次调用mygen()
时,执行都会继续,直到Python达到yield
表达式。因此,第一次调用mygen()
时,打印0
,但第二次打印1
。Python会记住它最后一次屈服的地方,并在那个时候恢复
因此,要将此想法应用到您的情况中,您可以尝试使用以下方法:
class NewDataFrame:
def __init__(self, parent, dataname):
...
self.on_done = self.cycle_done().next
self.doneButton = ttk.Button(parent, text="DONE", command=self.on_done)
def cycle_done(self):
while True:
for asp in (value.get().split(',')):
aspect = Aspect(self.dataSet.getName(), asp)
self.dataSet.addAspect(aspect)
for aspect in self.dataSet.getAspects():
self.createFile(i=aspect.getName())
self.instructions.configure(
text="enter groups of %s, separated by commas" % (aspect.getName()))
yield
for gro in (value.get().split(',')):
print(gro)
group = Group(self.dataSet.getName(), aspect.getName(), gro)
aspect.addGroup(group)
for group in aspect.getGroups():
self.createFile(i=aspect.getName(), j=group.getName())
self.instructions.configure(
text="enter members of %s, separated by commas" % (group.getName()))
yield
for mem in (value.get().split(',')):
member = Member(self.dataSet.getName(), aspect.getName(), group.getName(), mem)
group.addMember(member)
for mem in group.getMembers():
self.createFile(i=aspect.getName(), j=group.getName(), k=mem.getName())
yield
这将
createAspect
、createGroup
和createMembers
中的大部分代码组合到一个生成器中。可以重构循环_done
(到在(较小的)生成器上迭代的生成器中),但这样做会增加解决方案的复杂性。让我们先让这个解决方案起作用,然后(如果您感兴趣的话)我们可以担心重构。这不是一个太抽象或太不抽象的问题。相反,您必须提供最少的代码来重现您遇到的问题。这样做还可以帮助你发现/理解问题,其他人也可以有效地研究具体问题。非常感谢你为我指明了正确的方向。我将在这方面做一段时间,看看是否能完全理解。