Tk/Tkin中的事件流有问题

2024-10-02 00:41:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用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, 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:

^{pr2}$

我希望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()

我是一个大傻瓜,但这花了我很多的工作来制作,我真的被困在我的地方,所以我可以使用一些创造性的投入。我希望这个程序暂停帧并允许用户在value变量中为以下每种对象类型输入内容:aspects,它将包含组,它将包含成员(像树图一样组织)。在

目前,程序不会在createGroup的执行级别等待(我希望它在这里等待另一次单击以继续执行createMember部分),而是要求用户在输入方面之后立即输入成员。在

我希望这不是太抽象,非常感谢任何试图帮助的人。在


Tags: textinselfforvaluedefgroupdataset
1条回答
网友
1楼 · 发布于 2024-10-02 00:41:50

让我们从主要错误开始:

self.doneButton.configure(command=self.createGroups(aspect=a))

当Python到达这一行时,它计算self.createGroups(aspect=a),并将返回值传递给command。 所以self.createGroups(aspect=a)最终得到了调用。相反,您确实希望将回调函数传递给command,以便稍后调用(当按下next中的done按钮时)

试图通过重新配置done回调来管理控制流是自找麻烦。我们不仅要创建已经绑定了正确参数(例如aspect = a)的函数,因此我们有一个需要零参数的函数,正如done回调所期望的那样,而且(甚至更困难的是)我们必须识别何时从createMembers、createGroups和createAspect重置done回调。我们会对控制流程进行微观管理。在

如果我们能让Python处理这些细节,那不是很好吗?在

您要寻找的是一个函数,您可以调用、暂停、稍后返回,并在先前暂停的位置继续。 Python正好有这种函数a generator function。在

例如

^{pr2}$

收益率

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

这将来自createAspectcreateGroupcreateMembers的大部分代码合并到一个生成器中。可以重构cycle_done(到迭代(较小)生成器的生成器中),但这样做会增加解决方案的复杂性。让我们先让这个解决方案生效,然后(如果你感兴趣的话)我们可以考虑重构。在

相关问题 更多 >

    热门问题