gpt4 book ai didi

python - Tkinter - 运行时错误 : maximum recursion depth exceeded

转载 作者:太空狗 更新时间:2023-10-30 02:22:32 27 4
gpt4 key购买 nike

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

我现在正在做的是,最终给我错误:RuntimeError: maximum recursion depth exceeded while calling a Python object

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

最佳答案

处理一个 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__


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

这个例子将展示一些东西:

pack()grid() 可以在同一个 GUI 中使用,只要它们不共享 master。

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

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

• 如何使 GUI 在屏幕上真正居中。 (more information here)

• 如何使顶层窗口出现在与主窗口相同的位置。

• 两种防止顶层窗口被销毁的方法,因此只需要创建一次。

• 使 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()

关于python - Tkinter - 运行时错误 : maximum recursion depth exceeded,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10039485/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com