【问题标题】:Tkinter runtime error maximum recursion when open a window打开窗口时Tkinter运行时错误最大递归
【发布时间】:2015-05-21 10:25:18
【问题描述】:

其实我有一个大问题。 我已经有一个 tkinter 窗口,我想打开另一个。

import Tkinter
from Tkinter import *
import threading, time
from PIL import Image, ImageTk
from record_pd import *

class Gui_Record(Tkinter.Tk):

    def __init__(self, tkroot):
        self.root = Tk()
        self.root.title("Enregistreur")
        #self.root.geometry()                                                                                                                                                                                                                
        self.root.geometry("%dx%d+%d+%d" % (500, 70, 400, 300))
        self.root.c = Canvas(tkroot, bg='black')
        self.root.c.pack(fill=BOTH, expand=YES)
        self.initialize()
        self.recorder = RecordPd(tkroot)
        self.recorder.init_recorder()

    def initialize(self):
        #self.root.grid()                                                                                                                                                                                                                    

        self.root.resizable(False, False)

        self.Imgtmp = PhotoImage(file="img/record.png")
        self.imgclear = PhotoImage(file="img/clear.png")

        self.root.title = Tkinter.Label(self.root, text="Enregistreur Orgue Sensoriel", bg="black", fg="white", font=("Helvetica", 16))

        self.root.title.pack()

        self.root.button = Tkinter.Button(self, command=self.OnButtonClick, bg="black", bd=0)

        self.root.button.config(highlightthickness=0)
        self.root.button.config(activebackground="black")

        self.root.button.config(image=self.Imgtmp)
        self.root.button.pack()

        self.root.bind("<Destroy>", self._onDestroy)
        self.resume = True
        self.activate = False


    def setTkroot(self, tkroot):
        self.tkroot = tkroot

    def _onDestroy(self, e):
        self.resume = False
        self.recorder.stop_recording()


    def OnButtonClick(self):
       if (self.activate == False):
            self.resume = True
            self.recorder.open_wav()
            self.recorder.start_recording()
            thread = threading.Thread(target=self.threadClignoter)
            thread.start()
            self.activate = True
            print("In recording..")
       else:
            self.stopThread()
            self.recorder.stop_recording()
            self.activate = False

    def threadClignoter(self):
      isVisible = True

      while self.resume:
            if isVisible:
                clr = self.imgclear
            else:
                clr = self.Imgtmp

            self.root.button.config(image=clr)
            isVisible = not isVisible
            time.sleep(0.5)

    def stopThread(self):
        print("Record done.")
        self.resume = False
        self.root.button.config(image=self.Imgtmp)

当我调用我的对象时,我会这样做:

rec = Gui_Record(self.tkroot)
rec.mainloop()

当我启动一个窗口时,它没关系。但是当我将我的新窗口添加到我的父窗口时,它发生了:

traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__
    return self.func(*args)
  File "/home/naqued/Documents/assembla/backup/naqued-s-space/stido/gui_stido.py", line 139, in launch_recorder
    app = Gui_Record(self.tkroot)
  File "/home/naqued/Documents/assembla/backup/naqued-s-space/stido/record_gui.py", line 18, in __init__
    self.initialize()
  File "/home/naqued/Documents/assembla/backup/naqued-s-space/stido/record_gui.py", line 35, in initialize
    self.root.button = Tkinter.Button(self, command=self.OnButtonClick, bg="black", bd=0)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2128, in __init__
    Widget.__init__(self, master, 'button', cnf, kw)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2049, in __init__
    BaseWidget._setup(self, master, cnf)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2022, in _setup
    if not master:
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
    return getattr(self.tk, attr
.... ... ... ... .. .. ... 
  return getattr(self.tk, attr)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
    return getattr(self.tk, attr)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
    return getattr(self.tk, attr)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
    return getattr(self.tk, attr)
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1848, in __getattr__
    return getattr(self.tk, attr)
RuntimeError: maximum recursion depth exceeded while calling a Python object

我不对我的代码进行递归。 我不知道发生了什么,也没有在网上找到任何东西。

【问题讨论】:

  • sys.getrecursionlimit() 返回什么?
  • 我已经解决了这个问题,我会在几个小时内发布我的代码 :)

标签: python tkinter runtime tkinter-canvas


【解决方案1】:

您正在创建一个继承自 Tk 的类,但它创建了一个 Tk 的新实例,即使您没有显示它,您也是 在某个时候创建​​另一个根(对象作为tkroot 传入)我不确定这是否是唯一的问题,但肯定是a问题。

由于这是一个辅助窗口,您不应该从Tkinter.Tk 继承。相反,继承自Tkinter.Toplevel

您还有一个问题,即使这会创建一个新窗口作为 tkroot 的子窗口,但某些内部小部件正在创建为 tkroot 的子窗口,因此它们不会出现在此窗口中。

您还需要修复您的导入 - 您不应该从 Tk 进行全局导入,并且Tk 作为模块导入。

您可能还会遇到其他问题。 Tkinter 不适用于线程。我听说它有时可以在 linux 上运行,但通常你不应该从任何线程调用任何 GUI 函数,而不是创建小部件的线程。

【讨论】:

  • 谢谢,你的回答很有趣。我理解我的错误。我现在使用 Tkinter.Toplevel,因为正如我所读。这是创建其他窗口的最佳方式。是的,我也需要修复我的导入。还有一个递归问题,因为我记得 mainloop()(我的代码中有 2 个 mainloop())我会在几个小时内发布我的代码
  • @Naqued:你的程序应该只调用一次mainloop
  • 错误的导入会导致“运行时错误,最大递归..”我实际上调用了一个对象方法,当我调用它时,我的程序出现运行时错误,当我评论调用时,我的程序工作..我将学习一些在python中导入的技巧
  • @Naqued:错误的导入会导致最大递归错误吗?是的。当你导入一个模块时,里面的代码会被执行。如果模块中有错误代码,您可能会收到错误。
猜你喜欢
  • 2020-07-15
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 2016-03-06
相关资源
最近更新 更多