Python: 如何使用 main() 中定义的变量,and/or 使用包含两个 类 的列表而不会出错?

Python: How does one use variables defined in main(), and/or use a lists with two classes without errors?

Objective:我已经尝试在 main() 中使用变量并在我的代码中创建一个随机消息列表,这部分起作用了,但仍然出现多个我不知道的错误怎么修。

问题:有人可以修复我的代码以便错误消失,程序至少可以按预期运行吗?

在我的代码的 main() 部分中,我定义了几个按钮,我认为这会在第一个中断计时器之后弄乱我程序的计时器部分的 GUI。 objective 框应该重新出现在 window 中,但它没有。这也可能与 .destroy() 命令有关。我将如何修复它以便标签和条目小部件重新出现在初始 window?

这个问题有何不同:我知道有很多关于这些常见错误的问题,但我的代码是独一无二的,因此需要不同的 post。

代码:(这个应该都格式化对了,拉进你喜欢的IDE和运行调试)

from Tkinter import *
import time
import random


class PopUp():
    def __init__(self):
        top = self.top = Toplevel()
        self.inp = StringVar()
        self.nth = 0
        top.geometry("240x135+25+300")
        Label(top, text="Suggestion:").pack(side=TOP)
        self.message()
        Label(top, textvariable=self.inp)

    def message(self):
        self.inp.set(random.choice(self.mess))

    mess = ['Nice Job! Go take a walk outside!',
            'Nice Job! Wiggle your toes, and get back on it!',
            'Nice Job! Get up and walk around!',
            'Nice Job! Go get a drink of water!',
            'Good Work! Go take a walk outside!',
            'Good Work! Wiggle your toes, and get back on it!',
            'Good Work! Get up and walk around!',
            'Good Work! Go get a drink of water!']


class Timer(Frame):
    def __init__(self, stb, st, rb, qb, parent=None, **kw):
        Frame.__init__(self, parent, background="white")
        self.parent = parent
        self.initUI()
        self.inp = None
        self.stb = stb
        self.st = st
        self.rb = rb
        self.qb = qb
        self.timer1 = 9
        self.checkTimer1 = 1
        self.timer1Run = 0
        self.tempObj = 0
        self.entdat = StringVar()
        self.timestr = StringVar()
        self.makeTimer()
        self.makeWidgets()

   def initUI(self):
        self.parent.title("Timer")

    def makeWidgets(self):
        minutes = int(self.timer1/60)
        seconds = int(self.timer1 - minutes*60.0)
        self.timestr.set('%02d:%02d' % (minutes, seconds))
        self.ol = Label(text="Objective:")
        self.ol.pack(fill=X, expand=NO, pady=2, padx=2, side=TOP)
        self.ew = Entry(textvariable=self.entdat)
        self.ew.pack(fill=X, expand=NO, pady=2, padx=2, side=TOP)
        self.b = Button(text="OK", command=self.clicked)
        self.b.pack(side=TOP)


    def makeTimer(self):
        self.l = Label(self, textvariable=self.timestr)
        self.l.pack(fill=X, expand=NO, pady=2, padx=2)

    def makeButtons(self, st, stb, rb, qb):
        self.destroy()

    def updateTime(self):
        self.elapsed = time.time() - self.startTime
        self.curtim1 = self.timer1 - self.elapsed
        if self.curtim1 <= 0:
            self.stop()
            self.checkValue()

        else:
            minutes = int(self.curtim1/60)
            seconds = int(self.curtim1 - minutes*60.0)
            self.timestr.set('%02d:%02d' % (minutes, seconds))
            self.timer = self.after(1, self.updateTime)

    def checkValue(self):
        if self.checkTimer1 == 1:
            self.distroy_Widget()
            self.timer1 = 3
            self.checkTimer1 -= 1
            self.start()

        else:
            self.dat.destroy()
            self.makeWidgets()
            self.timer1 = 9
            self.checkTimer1 += 1
            pu = PopUp()
            pu.message()
            self.start()

    def start(self):
        if not self.timer1Run:
            self.startTime = time.time()
            self.updateTime()
            self.timer1Run = 1

    def stop(self):
         if self.timer1Run:
             self.after_cancel(self.timer)
             self.timer1Run = 0
             self.timer1 = self.curtim1

    def reset(self):
        self.timer1 = 900
        minutes = int(self.timer1/60)
        seconds = int(self.timer1 - minutes*60.0)

        self.timestr.set('%02d:%02d' % (minutes, seconds))

    def clicked(self):
        self.distroy_Widget()
        self.dat = Label(self, textvariable=self.entdat)
        self.dat.pack(side=TOP)

    def distroy_Widget(self):
        self.ew.destroy()
        self.ol.destroy()
        self.b.destroy()


def main():
    root = Tk()
    root.geometry("240x235+25+50")
    tm = Timer(root, stb, sb, rb, qb)
    tm.pack(side=TOP)

    sb = Button(root, text='Start', command=tm.start).pack(side=LEFT)
    stb = Button(root, text='Pause', command=tm.stop).pack(side=LEFT)
    rb = Button(root, text='Reset', command=tm.reset).pack(side=LEFT)
    qb = Button(root, text='Quit', command=root.quit).pack(side=LEFT)

    mainloop()

if __name__ == '__main__':
    main()

抱歉,您问题中的代码缩进不太正确。然而——忽略这个相对较小的问题以及它的以下修改版本并没有解决你所有的问题——你可能仍然会发现它很有用,因为它确实消除了关于在 main() 中使用变量的错误,方法是它们是 Timerclass 的所有属性,它们是唯一被引用的地方,并在其 __init__() 方法中初始化它们——本质上是@Mike Housky 在 中建议的。我还重命名了一些东西以使其更加一致。

这应该使 GUI 运行 足够好,让您可以自己处理剩余的问题。

from Tkinter import *
import time
import random

class PopUp():
    def __init__(self):
        top = self.top = Toplevel()
        self.inp = StringVar()
        self.nth = 0
        top.geometry("240x135+25+300")
        Label(top, text="Suggestion:").pack(side=TOP)
        self.message()
        Label(top, textvariable=self.inp)

    def message(self):
        self.inp.set(random.choice(self.mess))

    mess = ['Nice Job! Go take a walk outside!',
            'Nice Job! Wiggle your toes, and get back on it!',
            'Nice Job! Get up and walk around!',
            'Nice Job! Go get a drink of water!',
            'Good Work! Go take a walk outside!',
            'Good Work! Wiggle your toes, and get back on it!',
            'Good Work! Get up and walk around!',
            'Good Work! Go get a drink of water!']

class Timer(Frame):
    def __init__(self, parent=None, **kw):
        Frame.__init__(self, parent, background="white")
        self.initUI(parent)
        self.inp = None
        self.timer1 = 9
        self.checkTimer1 = 1
        self.timer1Run = 0
        self.tempObj = 0
        self.entdat = StringVar()
        self.timestr = StringVar()
        self.makeTimer()
        self.makeWidgets()

    def initUI(self, parent):
        self.parent = parent
        self.parent.title("Timer")
        self.sb = Button(self.parent, text='Start',
                         command=self.start).pack(side=LEFT)
        self.stb = Button(self.parent, text='Pause',
                          command=self.stop).pack(side=LEFT)
        self.rb = Button(self.parent, text='Reset',
                         command=self.reset).pack(side=LEFT)
        self.qb = Button(self.parent, text='Quit',
                         command=parent.quit).pack(side=LEFT)

    def makeWidgets(self):
        minutes = int(self.timer1/60)
        seconds = int(self.timer1 - minutes*60.0)
        self.timestr.set('%02d:%02d' % (minutes, seconds))
        self.ol = Label(text="Objective:")
        self.ol.pack(fill=X, expand=NO, pady=2, padx=2, side=TOP)
        self.ew = Entry(textvariable=self.entdat)
        self.ew.pack(fill=X, expand=NO, pady=2, padx=2, side=TOP)
        self.b = Button(text="OK", command=self.clicked)
        self.b.pack(side=TOP)

    def makeTimer(self):
        self.l = Label(self, textvariable=self.timestr)
        self.l.pack(fill=X, expand=NO, pady=2, padx=2)

    def updateTime(self):
        self.elapsed = time.time() - self.startTime
        self.curtim1 = self.timer1 - self.elapsed
        if self.curtim1 <= 0:
            self.stop()
            self.checkValue()
        else:
            minutes = int(self.curtim1/60)
            seconds = int(self.curtim1 - minutes*60.0)
            self.timestr.set('%02d:%02d' % (minutes, seconds))
            self.timer = self.after(1, self.updateTime)

    def checkValue(self):
        if self.checkTimer1 == 1:
            self.destroyWidgets()
            self.timer1 = 3
            self.checkTimer1 -= 1
            self.start()
        else:
            self.dat.destroy()
            self.makeWidgets()
            self.timer1 = 9
            self.checkTimer1 += 1
            pu = PopUp()
            pu.message()
            self.start()

    def start(self):
        if not self.timer1Run:
            self.startTime = time.time()
            self.updateTime()
            self.timer1Run = 1

    def stop(self):
         if self.timer1Run:
             self.after_cancel(self.timer)
             self.timer1Run = 0
             self.timer1 = self.curtim1

    def reset(self):
        self.timer1 = 900
        minutes = int(self.timer1/60)
        seconds = int(self.timer1 - minutes*60.0)
        self.timestr.set('%02d:%02d' % (minutes, seconds))

    def clicked(self):
        self.destroyWidgets()
        self.dat = Label(self, textvariable=self.entdat)
        self.dat.pack(side=TOP)

    def destroyWidgets(self):
        self.ew.destroy()
        self.ol.destroy()
        self.b.destroy()

def main():
    root = Tk()
    root.geometry("240x235+25+50")
    tm = Timer(root)
    tm.pack(side=TOP)
    mainloop()

if __name__ == '__main__':
    main()