RuntimeError:主线程不在主循环中;当我单击“退出”按钮时

时间:2017-03-29 13:19:35

标签: python python-3.x

我正在构建一个简单的GUI应用程序来计算某个事件的时间。无论如何,一切正常,但是当我点击退出按钮时,它开始每隔一秒给我一些异常,就像这样:

Exception in thread Thread-10: Traceback (most recent call last):   File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()   File "/usr/lib/python3.5/threading.py", line 1180, in run
    self.function(*self.args, **self.kwargs)   File "/home/cali/PycharmProjects/str8/str8", line 83, in printit
    display()   File "/home/cali/PycharmProjects/str8/str8", line 23, in display
    font="Verdana 8 bold").grid(row=0, sticky=W)   File "/usr/lib/python3.5/tkinter/__init__.py", line 2609, in __init__
    Widget.__init__(self, master, 'label', cnf, kw)   File "/usr/lib/python3.5/tkinter/__init__.py", line 2142, in __init__
    (widgetName, self._w) + extra + self._options(cnf)) RuntimeError: main thread is not in main loop

这就是我所做的:

# str8.py
#   Program to count time from a certain event

from tkinter import *
from datetime import *
from threading import *

root = Tk()
root.title("STR8")
root.resizable(width=False, height=False)

def main():
    printit()

def exit():
    root.destroy()

def display():
    event, tday, str8, seconds, minutes, hours, days, weeks, years = calculate()

    thelabel = Label(root,
                         text="You have been STR8 for:\n",
                         font="Verdana 8 bold").grid(row=0, sticky=W)

    labelYears = Label(root,
                           text="Years: "
                                + str(round(years, 2)),
                           font="Verdana 8").grid(row=1, sticky=W)

    labelWeeks = Label(root,
                           text="Weeks: "
                                + str(round(weeks, 2)),
                           font="Verdana 8").grid(row=2, sticky=W)

    labelDays = Label(root,
                          text="Days: "
                               + str(round(days, 2)),
                          font="Verdana 8").grid(row=3, sticky=W)

    labelHours = Label(root,
                           text="Hours: "
                                + str(round(hours, 2)),
                           font="Verdana 8").grid(row=4, sticky=W)

    labelMinutes = Label(root,
                             text="Minutes: "
                                  + str(round(minutes, 2)),
                             font="Verdana 8").grid(row=5, sticky=W)

    labelSeconds = Label(root,
                             text="Seconds: "
                                  + str(round(str8.total_seconds())),
                             font="Verdana 8").grid(row=6, sticky=W)

    buttonRefresh = Button(root,
                               text="EXIT",
                               font="Verdana 8",
                               height=1,
                               width=19,
                               command=exit).grid(row=7)


def calculate():
    event = datetime(2017, 3, 29, 13, 45, 0)
    tday = datetime.now()

    str8 = tday - event

    seconds = str8.total_seconds()
    minutes = str8.total_seconds() / 60
    hours = minutes / 60
    days = hours / 24
    weeks = days / 7
    years = weeks / 52

    return event, tday, str8, seconds, minutes, hours, days, weeks, years



def printit():
  Timer(1.0, printit).start()
  calculate()
  display()


main()
root.mainloop()

我正在使用Python 3.6。

1 个答案:

答案 0 :(得分:1)

以下程序似乎可以解决您的问题。 display中对print_it的调用包含在try块中。如果成功没有异常,则计时器将在稍后启动。

# str8.py
#   Program to count time from a certain event

from tkinter import *
from datetime import *
from threading import *

root = Tk()
root.title("STR8")
root.resizable(width=False, height=False)


def main():
    print_it()


def stop():
    root.destroy()


def display():
    event, today, str8, seconds, minutes, hours, days, weeks, years = calc()
    Label(root,
          text="You have been STR8 for:\n",
          font="Verdana 8 bold").grid(row=0, sticky=W)
    Label(root,
          text="Years: "
               + str(round(years, 2)),
          font="Verdana 8").grid(row=1, sticky=W)
    Label(root,
          text="Weeks: "
               + str(round(weeks, 2)),
          font="Verdana 8").grid(row=2, sticky=W)
    Label(root,
          text="Days: "
               + str(round(days, 2)),
          font="Verdana 8").grid(row=3, sticky=W)
    Label(root,
          text="Hours: "
               + str(round(hours, 2)),
          font="Verdana 8").grid(row=4, sticky=W)
    Label(root,
          text="Minutes: "
               + str(round(minutes, 2)),
          font="Verdana 8").grid(row=5, sticky=W)
    Label(root,
          text="Seconds: "
               + str(round(str8.total_seconds())),
          font="Verdana 8").grid(row=6, sticky=W)
    Button(root,
           text="EXIT",
           font="Verdana 8",
           height=1,
           width=19,
           command=stop).grid(row=7)


def calc():
    event = datetime(2017, 3, 29, 13, 45, 0)
    today = datetime.now()

    str8 = today - event

    seconds = str8.total_seconds()
    minutes = str8.total_seconds() / 60
    hours = minutes / 60
    days = hours / 24
    weeks = days / 7
    years = weeks / 52

    return event, today, str8, seconds, minutes, hours, days, weeks, years


def print_it():
    t = Timer(1.0, print_it)
    calc()
    try:
        display()
    except RuntimeError:
        pass
    else:
        t.start()


main()
root.mainloop()