此代码打开一个菜单,该菜单链接到另一个菜单。第一个按钮无法自行关闭并同时打开一个新按钮,该如何解决?
import tkinter as tk
import tkinter.messagebox as box
class EnterRLE(tk.Tk):
def __init__(self):
super().__init__()
self.title('Enter RLE')
self.line_count_str = tk.StringVar()
self.compressed_data_str = tk.StringVar(self)
frame = tk.Frame(self)
tk.Label(self, text='Line Count:').pack(padx=15, pady=5)
tk.Entry(self, bd=5, textvariable=self.line_count_str).pack(padx=15, pady=5)
tk.Button(self, text="Next", width=5, command=self.line_count_func).pack(side='right', padx=5)
tk.Button(self, text='Exit', width=5, command=self.destroy).pack(side='right', padx=5)
frame.pack(padx=100, pady=19)
def line_count_func(self):
if self.line_count_str.get().isdigit():
if int(self.line_count_str.get()) < 3:
box.showinfo(title="Error", message="Enter a number over 3")
elif int(self.line_count_str.get()) > 1000000000:
box.showinfo(title="Error", message="Enter a number under 1,000,000,000")
else:
self.enter_rle_2()
def enter_rle_2(self):
top = tk.Toplevel(self)
top.title('Enter RLE')
frame = tk.Frame(top)
tk.Label(top, text='Compressed Data:').pack(padx=15, pady=5)
tk.Entry(top, bd=5, textvariable=self.compressed_data_str).pack(padx=15, pady=5)
tk.Button(top, text="Next").pack(side='right', padx=5)
frame.pack(padx=19)
EnterRle1().mainloop()
我已经看到有人对这种类型的东西使用新的“ def”方法,但是我不确定如何使它们适应我的代码。
答案 0 :(得分:0)
这里有几个问题。
第一个主要问题是两次使用Tk()
。在这种特定情况下,清理代码后可以正常工作,但是通常您不希望使用多个Tk()
实例。
第二个主要问题是您如何尝试破坏enter_rle
函数中的linecount_button_clicked
。您无法执行此操作,因为该函数对单独的函数不了解enter_rle
。您需要在按钮命令中传递它。
第三个主要问题是int(linecount_STR.get())
。如果get抓住了一个数字或空字符串以外的东西,这将出错。因此,您的else
子句将永远不会发生,因为它将在您的if/else
语句之前出错。因此,请使用isdigit()
进行修复。
下一步,即使在这里没有任何问题,您仍想在函数顶部定义全局变量。
此处存在一些PEP8问题,这些问题不会损害代码,但如果将它们清理干净,将使其更易于阅读。
确实应该将其构建在类中,以便我们可以使用类属性和方法来管理所有内容。
这是您清理的代码,如果您有任何疑问,请告诉我。
from tkinter import *
import tkinter.messagebox as box
def enter_rle_1():
enter_rle = Tk()
linecount_STR = StringVar()
enter_rle.title('Enter RLE')
frame = Frame(enter_rle)
label_linecount = Label(enter_rle, text='Linecount:')
label_linecount.pack(padx=15, pady=5)
linecount = Entry(enter_rle, bd=5, textvariable=linecount_STR)
linecount.pack(padx=15, pady=5)
ok_button = Button(enter_rle, text="Next", width=5,
command=lambda lc=linecount_STR: linecount_button_clicked(enter_rle, lc))
ok_button.pack(side=RIGHT, padx=5)
stop = Button(enter_rle, text='Exit', width=5, command=enter_rle.destroy)
stop.pack(side=RIGHT, padx=5)
frame.pack(padx=100, pady=19)
enter_rle.mainloop()
def linecount_button_clicked(enter_rle, linecount_STR):
linecount = linecount_STR.get()
if linecount.isdigit(): # does nothing if value is not a digit.
if int(linecount) < 3:
box.showinfo(title="Error", message="Enter a number over 3")
elif int(linecount) > 1000000000:
box.showinfo(title="Error", message="Enter a number under 1,000,000,000")
else:
enter_rle_2(enter_rle)
def enter_rle_2(root):
enter_rle = Toplevel(root)
compressed_data_STR = StringVar(root)
enter_rle.title('Enter RLE')
frame = Frame(enter_rle)
label_compressed_data = Label(enter_rle, text='Compressed Data:')
label_compressed_data.pack(padx=15, pady=5)
compressed_data = Entry(enter_rle, bd=5, textvariable=compressed_data_STR)
compressed_data.pack(padx=15, pady=5)
ok_button = Button(enter_rle, text="Next")
ok_button.pack(side=RIGHT, padx=5)
frame.pack(padx=100, pady=19)
enter_rle_1()
这是使用类属性和方法的代码的OOP版本。在Tkinter中管理此类交互更加容易,并且不再需要全球性的交互。
import tkinter as tk
import tkinter.messagebox as box
class EnterRle1(tk.Tk):
def __init__(self):
super().__init__()
self.title('Enter RLE')
self.line_count_str = tk.StringVar()
self.compressed_data_str = tk.StringVar(self)
frame = tk.Frame(self)
tk.Label(self, text='Line Count:').pack(padx=15, pady=5)
tk.Entry(self, bd=5, textvariable=self.line_count_str).pack(padx=15, pady=5)
tk.Button(self, text="Next", width=5, command=self.line_count_func).pack(side='right', padx=5)
tk.Button(self, text='Exit', width=5, command=self.destroy).pack(side='right', padx=5)
frame.pack(padx=100, pady=19)
def line_count_func(self):
if self.line_count_str.get().isdigit():
if int(self.line_count_str.get()) < 3:
box.showinfo(title="Error", message="Enter a number over 3")
elif int(self.line_count_str.get()) > 1000000000:
box.showinfo(title="Error", message="Enter a number under 1,000,000,000")
else:
self.enter_rle_2()
def enter_rle_2(self):
top = tk.Toplevel(self)
top.title('Enter RLE')
frame = tk.Frame(top)
tk.Label(top, text='Compressed Data:').pack(padx=15, pady=5)
tk.Entry(top, bd=5, textvariable=self.compressed_data_str).pack(padx=15, pady=5)
tk.Button(top, text="Next").pack(side='right', padx=5)
frame.pack(padx=100, pady=19)
EnterRle1().mainloop()