Обновление рамки tkinter при нажатии кнопки
Я использую код из Switch между двумя кадрами в tkinter, чтобы сделать мой графический интерфейс. У меня есть рамка с кнопками обновления и перезагрузки.
Моя первоначальная идея состояла в том, чтобы кнопка перезагрузки перешла на стартовую страницу, как показано в коде ниже, но если этот кадр вызывается снова, в нем все еще отображаются записи из предыдущей попытки.
Я попытался.destroy() для кнопки обновления, но затем я получаю сообщение трассировки при повторном вызове кадра PLG.
Для кнопки перезагрузки, как бы я закрыл рамку PLG, перешел на начальную страницу и затем смог бы снова выбрать PLG?
Для кнопки обновления, как бы я удалил записи в виджете ввода и текстовой задолженности, чтобы можно было сделать другую запись и вернуть новый ответ?
class PLG(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Enter the engine size (cc) below", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
vcmd = (self.register(self.onValidate), '%S')
self.weight_entry = tk.Entry(self, validate='key', vcmd = vcmd)
self.weight_entry.pack(pady = 10)
tk.Button(self, text='Click here to display price', command=self.show_option).pack()
self.text = tk.Text(self)
self.text.pack(pady = 10)
self.text.config(state='disabled')
restart_button = tk.Button(self, text="Restart",
command=self.restart)
restart_button.pack()
refresh_button = tk.Button(self, text="Refresh", command=self.refresh).pack()
refresh_button.pack()
def onValidate(self,S):
if S in ['0','1','2', '3', '4', '5', '6', '7', '8', '9']:
return True
else:
self.bell() # adds a sound effect to error
self.text.delete(1.0, tk.END) # deletes the error message if valid entry provided
self.text.insert(tk.END, "Invalid entry. Please try again.") # displays an error message if a number not provided in entry widget
return False
def restart(self):
self.refresh()
show_frame("StartPage")
def refresh(self):
self.text.config(state='normal')
self.weight_entry.delete(0,tk.END)
self.text.delete("1.0", "end")
Консультации по обоим элементам будут оценены.
2 ответа
Первый шаг - заставить вашу кнопку вызывать правильную функцию, а не использовать lambda
, Если вы не понимаете, почему и когда использовать lambda
обычно это только затрудняет написание и понимание кода.
Когда у вас есть вызов функции, вы можете использовать функцию для очистки записей.
Пример:
class PLG(tk.Frame):
def __init__(self, parent, controller):
...
tk.Button(self, text="Restart", command=self.restart)
tk.Button(self, text="Refresh", command=self.refresh)
...
def restart(self):
self.refresh()
self.controller.show_frame("StartPage")
def refresh(self):
self.weight_entry.delete(0, "end")
self.text.delete("1.0", "end")
Вопрос ОП касался очистки полей ввода, поэтому предыдущий ввод еще не был на странице, когда вы ожидали увидеть пустые поля для нового ввода. Я публикую готовый код, опуская возможности оригинального кода OP, которые не имеют отношения к его вопросу, поэтому решение можно легко увидеть в полном контексте. Я пытался решить эту проблему с помощью того же кода с переключением кадров из знаменитых руководств Брайана Оукли по этой теме. Я также включил альтернативную версию, используя grid_remove вместо tkraise, поскольку именно так я решил проблему постоянно активных, но невидимых фреймов, пытающихся участвовать в обходе фокуса, когда пользователь пытается перемещаться по странице. Это также удерживало кадры от всех попыток быть одинакового размера.
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
# alternate ways to create the frames & append to frames dict: comment out one or the other
for F in (StartPage, PLG):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
# self.frames["StartPage"] = StartPage(parent=container, controller=self)
# self.frames["PLG"] = PLG(parent=container, controller=self)
# self.frames["StartPage"].grid(row=0, column=0, sticky="nsew")
# self.frames["PLG"].grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
# alternate version of show_frame: comment out one or the other
def show_frame(self, page_name):
for frame in self.frames.values():
frame.grid_remove()
frame = self.frames[page_name]
frame.grid()
# def show_frame(self, page_name):
# frame = self.frames[page_name]
# frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="start page")
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One", command=lambda: controller.show_frame("PLG"))
button1.pack()
button2 = tk.Button(self, text="focus traversal demo only")
button2.pack()
button2.focus_set()
button3 = tk.Button(self, text="another dummy button")
button3.pack()
lbl = tk.Label(self, text="tkraise messes up focus traversal\nwhich you can see by testing the two versions of show_frame.()\nUsing grid_remove instead of tkraise solves that,\nwhile preventing frames from being unable to resize to fit their own contents.")
lbl.pack()
class PLG(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Enter something below; the two buttons clear what you type.")
label.pack(side="top", fill="x", pady=10)
self.wentry = tk.Entry(self)
self.wentry.pack(pady = 10)
self.text = tk.Text(self)
self.text.pack(pady = 10)
restart_button = tk.Button(self, text="Restart", command=self.restart)
restart_button.pack()
refresh_button = tk.Button(self, text="Refresh", command=self.refresh)
refresh_button.pack()
def restart(self):
self.refresh()
self.controller.show_frame("StartPage")
def refresh(self):
self.wentry.delete(0, "end")
self.text.delete("1.0", "end")
# set focus to any widget except a Text widget so focus doesn't get stuck in a Text widget when page hides
self.wentry.focus_set()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
Простой способ: просто вызвать это окно кнопкой или привязать, в котором находится фрейм.
хорошо работает для обновления окон.