当前位置: 首页 > 知识库问答 >
问题:

Tkinter - 运行时错误:超出最大递归深度

汪玮
2023-03-14

周一开始用Python编程。我喜欢学习它。但是当在tkinter菜单之间切换时,我一直试图理解如何避免递归。我确信这是一个非常基本的问题,我很感激你能容忍我在这个问题上的无知,但是我在别处找不到答案。

我现在所做的是,最终给了我一个错误:RuntimeError:调用Python对象时超出了最大递归深度

这是我目前使用的模式。更新:下面的代码现在是一个完整的、独立的副本,重现了我面临的问题!:D

from tkinter import *

def mainmenu():
    global frame, root

    frame.destroy()

    frame = Frame()
    frame.pack()

    button1 = Button(frame, text="anothermenulikethis", command = anothermenulikethis)
    button2 = Button(frame, text="anothermenulikethis", command = anothermenulikethis)
    button3 = Button(frame, text="mainmenu", command = mainmenu)

    button1.pack(side=LEFT)
    button2.pack(side=LEFT)
    button3.pack(side=LEFT)

    root.mainloop()

def anothermenulikethis():
    global frame, root

    frame.destroy()

    frame = Frame()
    frame.pack()

    button1 = Button(frame, text="mainmenu", command = mainmenu)
    button2 = Button(frame, text="mainmenu", command = mainmenu)
    button3 = Button(frame, text="anothermenulikethis", command = anothermenulikethis)

    button1.pack(side=LEFT)
    button2.pack(side=LEFT)
    button3.pack(side=LEFT)

    root.mainloop()

root = Tk()
root.title("Recursive Menu Problem Isolation")
root.geometry("1200x600")
frame = Frame()

mainmenu()

一切都工作正常,直到它不可避免地从最大递归深度失败。如果有人能提出更好的做事方法,或者有一个更好的方法的例子的链接,我渴望学习。

PS:我已经研究并尝试增加递归深度,但我觉得这是一个穷人的解决方案,是我的方法的一个根本问题。

提前谢谢大家了。

根据要求,以下是回溯:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/tkinter/__init__.py", line 1399, in __call__
    return self.func(*args)
  File "/Users/diligentstudent/Desktop/menutest.py", line 11, in mainmenu
    button1 = Button(frame, text="anothermenulikethis", command = anothermenulikethis)
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/tkinter/__init__.py", line 2028, in __init__
    Widget.__init__(self, master, 'button', cnf, kw)
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/tkinter/__init__.py", line 1958, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/tkinter/__init__.py", line 1043, in _options
    v = self._register(v)
  File "/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/tkinter/__init__.py", line 1079, in _register
    f = CallWrapper(func, subst, self).__call__
RuntimeError: maximum recursion depth exceeded

共有2个答案

壤驷鸿
2023-03-14

这个问题的其他人注意:你的按钮命令可能没有在适当的缩进层次!在深入研究之前,请检查它是否与您的其他类方法内联。不久前我自己也遇到了这个问题,重新检查我的压痕修复了一切。

燕富
2023-03-14

处理tkinter GUI只需要一个mainloop()

话虽如此,我认为您只需要一个类结构的示例

from tkinter import Tk,Button

class Application(Tk):

    def say_hi(self):
        print('Hello world?!')

    def close_app(self):
        self.destroy()

    def create_Widgets(self):
        self.quitButton = Button(self, width=12, text='Quit', bg='tan',
                    command=self.close_app)
        self.quitButton.grid(row=0, column=0, padx=8, pady=8)

        self.helloButton = Button(self, width=12, text='Hello',
                    command=self.say_hi)
        self.helloButton.grid(row=0, column=1, padx=8, pady=8)

    def __init__(self):
        Tk.__init__(self)
        self.title('Hello world!')
        self.create_Widgets()

app = Application()
app.mainloop()

为了避免与其他模块可能发生的冲突,有些人更喜欢像这样导入
(清楚地说明所有内容的来源):

import tkinter as tk

class Application(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.title('Hello world!')

        self.quitButton = tk.Button(self, width=12, text='Quit', bg='tan',
                    command=self.close_app)
        self.quitButton.grid(row=0, column=0, padx=8, pady=8)

        self.helloButton = tk.Button(self, width=12, text='Hello',
                    command=self.say_hi)
        self.helloButton.grid(row=0, column=1, padx=8, pady=8)

    def say_hi(self):
        print('Hello world?!')

    def close_app(self):
        self.destroy()

app = Application()
app.mainloop()

如您所见,创建小部件很容易在__init__

我决定根据我在过去一个月学到的东西做一个更实用/更有教育意义的例子。在这样做的时候,我有一点启示:并不是所有的东西都需要一个自我。类中的前缀!对于tkinter类尤其如此,因为您不会将其作为主程序中的对象进行操作。当您稍后要在方法中使用某些东西时,大多数情况下您需要自我。前缀。前面的例子显示了任何东西(如按钮)如何接收自我。前缀,即使是完全不必要的。

本示例将显示以下内容:

•<code>pack()</code>和<code>grid()<-code>可以在同一个GUI中使用,只要它们不共享一个主机。

文本小部件可以在字体大小更改时不展开。

• 如何打开和关闭所选文本的粗体标签。

•如何在屏幕上真正居中显示GUI。(更多信息请点击此处)

•如何使顶层窗口相对于主窗口出现在同一位置。

有两种方法可以防止顶层窗口被破坏,因此只需要创建一次。

•使ctrl a(全选)功能正常。

import tkinter as tk
import tkFont

class Application(tk.Tk):

    def __init__(self):
        tk.Tk.__init__(self)
        self.title('T-Pad')

    # Menubar

        menubar = tk.Menu(self)

        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Exit", command=self.close_app)
        menubar.add_cascade(label="File", menu=filemenu)

        formatmenu = tk.Menu(menubar, tearoff=0)
        formatmenu.add_command(label="Font", command=self.show_sizeWin)
        menubar.add_cascade(label="Format", menu=formatmenu)

        self.config(menu=menubar)

    # Bold Button

        boldButton = tk.Button(self, width=12, text='Bold',
                                command=self.make_bold)
        boldButton.pack()

    # Text widget, its font and frame

        self.defaultFont = tkFont.Font(name="defFont")

        textFrame = tk.Frame(self, borderwidth=1, relief="sunken",
                             width=600, height=600)

        textFrame.grid_propagate(False) # ensures a consistent GUI size
        textFrame.pack(side="bottom", fill="both", expand=True)


        self.mText = tk.Text(textFrame, width=48, height=24, wrap='word',
                            font="defFont")
        self.mText.grid(row=0, column=0, sticky="nsew")

    # Scrollbar and config

        tScrollbar = tk.Scrollbar(textFrame, command=self.mText.yview)
        tScrollbar.grid(row=0, column=1, sticky='nsew', pady=1)

        self.mText.config(yscrollcommand=tScrollbar.set)

    # Stretchable

        textFrame.grid_rowconfigure(0, weight=1)
        textFrame.grid_columnconfigure(0, weight=1)

    # Bold Tag

        self.bold_font = tkFont.Font(self.mText, self.mText.cget("font"))
        self.bold_font.configure(weight="bold")
        self.mText.tag_configure("bt", font=self.bold_font)

    # Center main window

        self.update_idletasks()

        xp = (self.winfo_screenwidth() / 2) - (self.winfo_width() / 2) - 8
        yp = (self.winfo_screenheight() / 2) - (self.winfo_height() / 2) - 30
        self.geometry('{0}x{1}+{2}+{3}'.format(self.winfo_width(), self.winfo_height(),
                                                                                xp, yp))

    # Font Size Window (notice that self.sizeWin is given an alias)

        sizeWin = self.sizeWin = tk.Toplevel(self, bd=4, relief='ridge')

        self.sizeList = tk.Listbox(sizeWin, width=10, height=17, bd=4,
                                font=("Times", "16"), relief='sunken')

        self.sizeList.grid()

        doneButton = tk.Button(sizeWin, text='Done', command=sizeWin.withdraw)
        doneButton.grid()

        for num in range(8,25):
            self.sizeList.insert('end', num)

        sizeWin.withdraw()

        sizeWin.overrideredirect(True) # No outerframe!
        # Below is another way to prevent a TopLevel window from being destroyed.
        # sizeWin.protocol("WM_DELETE_WINDOW", self.callback)

    # Bindings
        # Double click a font size in the Listbox
        self.sizeList.bind("<Double-Button-1>", self.choose_size)
        self.bind_class("Text", "<Control-a>", self.select_all)

##    def callback(self):
##        self.sizeWin.withdraw()

    def select_all(self, event):
        self.mText.tag_add("sel","1.0","end-1c")

    def choose_size(self, event=None):
        size_retrieved = self.sizeList.get('active')
        self.defaultFont.configure(size=size_retrieved)
        self.bold_font.configure(size=size_retrieved)

    def show_sizeWin(self):
        self.sizeWin.deiconify()
        xpos = self.winfo_rootx() - self.sizeWin.winfo_width() - 8
        ypos = self.winfo_rooty()
        self.sizeWin.geometry('{0}x{1}+{2}+{3}'.format(self.sizeWin.winfo_width(),
                                                self.sizeWin.winfo_height(), xpos, ypos))

    def make_bold(self):
        try:
            current_tags = self.mText.tag_names("sel.first")
            if "bt" in current_tags:
                self.mText.tag_remove("bt", "sel.first", "sel.last")
            else:
                self.mText.tag_add("bt", "sel.first", "sel.last")
        except tk.TclError:
            pass

    def close_app(self):
        self.destroy()

app = Application()
app.mainloop()
 类似资料:
  • 这是我的代码。打印map_appliance_info(df_appliance)时,我收到错误- 文件"E:/iisc/code/try.py",第69行,map_appliance_infodf_appliance_mapped=map_appliance_info(df_appliance) 文件“E:/iisc/code/try.py”,第35行,map_appliance_info中的i

  • 问题内容: 我从星期一开始使用Python进行编程。我很喜欢学习它。但是我一直试图了解如何在tkinter菜单之间切换时避免递归!我确信这是一个非常基本的问题,感谢您宽容我对此主题的无知,但我无法在其他地方找到答案。 我现在正在做的最终是给我错误:RuntimeError:调用Python对象时超出了最大递归深度 这是我目前正在使用的模式。更新:下面的代码现在是完整的隔离副本,再现了我面临的问题!

  • 问题内容: 我使用以下代码解决了Euler项目的问题10,该代码通过强力工作: 这三个功能的工作方式如下: isPrime 检查数字是否为质数; primeList 返回一个列表,其中包含一组在一定范围内且限制为“ n”的素数,并且; sumPrimes 对列表中所有数字的值求和。(不需要最后一个功能,但是我喜欢它的清晰度,特别是对于像我这样的初学者。) 然后,我编写了一个新函数 primeLis

  • 我似乎不知道如何使工作。如何修复此问题,使矩形继续向下移动?

  • 我不明白为什么我会得到这个最大深度错误。iam试图使用bst递归方法在数组中查找数字索引,下面是我的代码 任何人都可以告诉我代码块中发生了什么 错误块: PS C:\Users\admin\Desktop\DSA

  • 我正在使用Python进行合并排序。 我已经勾选了< code >合并功能。阵列融合得很好。 但在函数中,将出现错误:--- RuntimeError:超过最大递归深度。 运行时错误回溯(最近一次调用)在 () 63 打印(arr[i]), 64 --- 在合并排序(arr,l,r)53 m=l(r-1)/2 54合并排序(ar,l,m)--- 可能的原因是什么?