Tkinter和线程.堆栈空间不足(无限循环?) [英] Tkinter and thread. out of stack space (infinite loop?)

查看:137
本文介绍了Tkinter和线程.堆栈空间不足(无限循环?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Tkinter和线程机制.谁能解释这引发异常的原因:

I'm experimenting with Tkinter and the threads mechanism. Can anyone explain why this raises the exception:

<class '_tkinter.TclError'> out of stack space (infinite loop?)

该如何解决呢?下面是代码.顺便说一句,我知道有人建议使用线程模块而不是线程,但是现在我想使用线程模块,它只是为了向我介绍该机制而更加简单.

and how can I solve this? Below is the code. BTW, I know some people suggest to use the threading module instead of thread, but for now I'd like to use the thread module which is simpler just to introduce myself to the mechanism.

from Tkinter import *
import thread
import time

def main_thread(master):

    try:
        frame = Frame(master)
        frame.pack(side='bottom')
        scrollbar = Scrollbar(master)
        scrollbar.pack(side='right',fill='y')

        t = "Title"
        title = StringVar()
        title.set(t)
        ttl = Label(master, textvariable=title, font=("Helvetica", 18))
        ttl.pack(side='top')
        cont = Text(master, font=("Helvetica",14), yscrollcommand=scrollbar.set)
        cont.pack(side='bottom')
        button = Button(frame,text="Exit", command=root.destroy)
        button.pack(side='bottom')

        n = 0
        while 1:
            n += 1
            cont.insert('end', str(n)+"\n")
            time.sleep(1)

    except Exception as e:
        print type(e), e

if __name__ == '__main__':

    root = Tk()
    root.title("My counting application")
    thread.start_new_thread(main_thread, (root,)) # FIXME: out of stack space (infinite loop?)
    root.mainloop()

谢谢你, 卢卡

编辑

我解决了替代问题

    n = 0
    while 1:
        n += 1
        cont.insert('end', str(n)+"\n")
        time.sleep(1)

使用

    n = 0
    def do_every_second(n):
        cont.insert("end", str(n) + "\n")
        n += 1
        master.after(1000, do_every_second, n)
    do_every_second(n)

并致电

main_thread(root)

代替

thread.start_new_thread(main_thread, (root,))

推荐答案

您的代码中有几个致命的缺陷.首先,您根本无法编写从多个线程接触tkinter小部件的代码.您正在主线程中创建根窗口,因此只能从主线程直接访问小部件. Tkinter不是线程安全的.

You have a couple of fatal flaws in your code. For one, you simply can't write code that touches tkinter widgets from more than one thread. You are creating the root window in the main thread, so you can only ever directly access widgets from the main thread. Tkinter is not thread safe.

第二个问题是您有一个无限循环,该循环不断附加到文本小部件.它别无选择,只能最终耗尽内存.

The second problem is that you have an infinite loop that is constantly appending to the text widget. It has no choice but to eventually run out of memory.

要解决您的问题,您应该:

To solve your problem you should:

  1. 没有永远附加到文本小部件的无限循环
  2. 不能从多个线程访问任何小部件

如果您想每秒运行一次函数,有比线程更好的方法.简而言之:

If you want to run a function once a second, there are better ways to do that than with threads. In short:

def do_every_second():
    cont.insert("end", str(n) + "\n")
    root.after(1000, do_every_second)

这将导致do_every_second做任何事情,然后安排自己在将来的一秒钟内再次被调用.

This will cause do_every_second to do whatever it does, then arranges for itself to be called again one second in the future.

这篇关于Tkinter和线程.堆栈空间不足(无限循环?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆