Tkinter Entry() 不从输入中获取数字
Tkinter Entry() don't get numbers from input
我对 Tkinter Entry
有疑问。我是 运行 循环中的程序,创建和销毁两个 class 实例。在初始循环中,一切正常。游戏结束后,我将销毁 Tkinter 实例:
self.frame.destroy()
self.tk.destroy()
然后程序回到主循环:
def main():
root = Tk()
data = get_data(root)
root.mainloop()
del root
root = Tk()
main_window = Main_field(root, data)
root.mainloop()
del data, root, main_window
msg = "Play again?"
res = messagebox.askyesno("Game Over", message=msg)
if res:
del res
main()
else:
quit()
此循环的主要对象是创建新的空 class 实例,作为第一个实例。问题是重新启动后输入框不加载输入数字。当我调用 get() 方法时,我有一个空字符串:
class get_data():
def __init__(self, tk):
global mines_var
mines_var = tkinter.StringVar()
entry_box_mines = Entry(tk, textvariable=mines_var, width=50)
entry_box_mines.pack()
entry_box_mines.insert(0, 0)
self.width = 0
self.len_ = 0
self.mines = 0
self.tk = tk
start_game_button = Button(tk, text="Start Game", command=lambda: [self.get_attributes()]).pack()
def get_attributes(self):
res = self.validate(len_var.get(), width_var.get(), mines_var.get())
if res == "OK":
self.tk.destroy()
else:
messagebox.showinfo(message=res)
我哪里出错了?
你的错误是
mines_var = tkinter.StringVar()
从 mines_var
中删除了之前的 tkinter.StringVar()
并删除了之前的值。
您应该只将值保留在全局变量中,然后再将其放回 StringVar()
。
您还应该使用父级 - tk
- 就像在小部件中一样。
mines_var = tkinter.StringVar(parent, value=global_value)
我的版本有其他改动。
PEP 8-- Style Guide for Python Code
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import messagebox
# --- classes ---
class GetDataWindow(): # PEP8: `CamelCaseNames` for classes, and `noun` as name (PL: rzeczownik)
def __init__(self):
self.root = tk.Tk()
# variables
print('[DEBUG] __init__:', global_len, global_width, global_mines)
self.len_var = tk.StringVar(self.root, value=global_len)
self.width_var = tk.StringVar(self.root, value=global_width)
self.mines_var = tk.StringVar(self.root, value=global_mines)
# widgets
tk.Label(self.root, text='Settings').grid(row=0, column=0, columnspan=2)
tk.Label(self.root, text='len:').grid(row=1, column=0, sticky='e')
tk.Entry(self.root, textvariable=self.len_var).grid(row=1, column=1)
tk.Label(self.root, text='width:').grid(row=2, column=0, sticky='e')
tk.Entry(self.root, textvariable=self.width_var).grid(row=2, column=1)
tk.Label(self.root, text='mines:').grid(row=3, column=0, sticky='e')
tk.Entry(self.root, textvariable=self.mines_var).grid(row=3, column=1)
tk.Button(self.root, text="Start Game", command=self.get_attributes).grid(row=4, column=0, columnspan=2)
self.root.mainloop()
def get_attributes(self):
global global_len
global global_width
global global_mines
res = self.validate(self.len_var.get(), self.width_var.get(), self.mines_var.get())
if res == "OK":
global_len = self.len_var.get()
global_width = self.width_var.get()
global_mines = self.mines_var.get()
print('[DEBUG] get_attributes:', global_len, global_width, global_mines)
self.root.destroy()
else:
messagebox.showinfo(message=res)
def validate(self, *values):
return 'OK'
class MainWindow():
def __init__(self):
self.root = tk.Tk()
tk.Label(self.root, text='Game').grid(row=0, column=0, columnspan=2)
tk.Label(self.root, text='len:').grid(row=1, column=0, sticky='e')
tk.Label(self.root, text=global_len).grid(row=1, column=1)
tk.Label(self.root, text='width:').grid(row=2, column=0, sticky='e')
tk.Label(self.root, text=global_width).grid(row=2, column=1)
tk.Label(self.root, text='mines:').grid(row=3, column=0, sticky='e')
tk.Label(self.root, text=global_mines).grid(row=3, column=1)
tk.Button(self.root, text="OK", command=self.root.destroy).grid(row=4, column=0, columnspan=2)
self.root.mainloop()
# --- main ---
# default value at start
global_len = '0'
global_width = '0'
global_mines = '0'
while True:
GetDataWindow()
MainFieldWindow()
#win = GetDataWindow()
#del win
#win = MainWindow()
#del win
# create and hide main window before creating message
root = tk.Tk()
root.withdraw()
res = messagebox.askyesno("Game Over", message="Play again?")
if not res:
break
root.destroy()
顺便说一句:
当然可以不用关键字global
,比如:
len_ = 0
width = 0
mines = 0
while True:
win = GetDataWindow(len_, width, mines)
len_ = win.len_
width = win.width
mines = win.mines
MainWindow(len_, width, mines)
# ... the rest ...
或更简单:
settings = {
'len': 0,
'width': 0,
'mines': 0,
}
while True:
GetDataWindow(settings)
MainWindow(settings)
# ... the rest ...
但是我跳过了这部分。
我也可以使用 IntVar
而不是 StringVar
。
我对 Tkinter Entry
有疑问。我是 运行 循环中的程序,创建和销毁两个 class 实例。在初始循环中,一切正常。游戏结束后,我将销毁 Tkinter 实例:
self.frame.destroy()
self.tk.destroy()
然后程序回到主循环:
def main():
root = Tk()
data = get_data(root)
root.mainloop()
del root
root = Tk()
main_window = Main_field(root, data)
root.mainloop()
del data, root, main_window
msg = "Play again?"
res = messagebox.askyesno("Game Over", message=msg)
if res:
del res
main()
else:
quit()
此循环的主要对象是创建新的空 class 实例,作为第一个实例。问题是重新启动后输入框不加载输入数字。当我调用 get() 方法时,我有一个空字符串:
class get_data():
def __init__(self, tk):
global mines_var
mines_var = tkinter.StringVar()
entry_box_mines = Entry(tk, textvariable=mines_var, width=50)
entry_box_mines.pack()
entry_box_mines.insert(0, 0)
self.width = 0
self.len_ = 0
self.mines = 0
self.tk = tk
start_game_button = Button(tk, text="Start Game", command=lambda: [self.get_attributes()]).pack()
def get_attributes(self):
res = self.validate(len_var.get(), width_var.get(), mines_var.get())
if res == "OK":
self.tk.destroy()
else:
messagebox.showinfo(message=res)
我哪里出错了?
你的错误是
mines_var = tkinter.StringVar()
从 mines_var
中删除了之前的 tkinter.StringVar()
并删除了之前的值。
您应该只将值保留在全局变量中,然后再将其放回 StringVar()
。
您还应该使用父级 - tk
- 就像在小部件中一样。
mines_var = tkinter.StringVar(parent, value=global_value)
我的版本有其他改动。
PEP 8-- Style Guide for Python Code
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import messagebox
# --- classes ---
class GetDataWindow(): # PEP8: `CamelCaseNames` for classes, and `noun` as name (PL: rzeczownik)
def __init__(self):
self.root = tk.Tk()
# variables
print('[DEBUG] __init__:', global_len, global_width, global_mines)
self.len_var = tk.StringVar(self.root, value=global_len)
self.width_var = tk.StringVar(self.root, value=global_width)
self.mines_var = tk.StringVar(self.root, value=global_mines)
# widgets
tk.Label(self.root, text='Settings').grid(row=0, column=0, columnspan=2)
tk.Label(self.root, text='len:').grid(row=1, column=0, sticky='e')
tk.Entry(self.root, textvariable=self.len_var).grid(row=1, column=1)
tk.Label(self.root, text='width:').grid(row=2, column=0, sticky='e')
tk.Entry(self.root, textvariable=self.width_var).grid(row=2, column=1)
tk.Label(self.root, text='mines:').grid(row=3, column=0, sticky='e')
tk.Entry(self.root, textvariable=self.mines_var).grid(row=3, column=1)
tk.Button(self.root, text="Start Game", command=self.get_attributes).grid(row=4, column=0, columnspan=2)
self.root.mainloop()
def get_attributes(self):
global global_len
global global_width
global global_mines
res = self.validate(self.len_var.get(), self.width_var.get(), self.mines_var.get())
if res == "OK":
global_len = self.len_var.get()
global_width = self.width_var.get()
global_mines = self.mines_var.get()
print('[DEBUG] get_attributes:', global_len, global_width, global_mines)
self.root.destroy()
else:
messagebox.showinfo(message=res)
def validate(self, *values):
return 'OK'
class MainWindow():
def __init__(self):
self.root = tk.Tk()
tk.Label(self.root, text='Game').grid(row=0, column=0, columnspan=2)
tk.Label(self.root, text='len:').grid(row=1, column=0, sticky='e')
tk.Label(self.root, text=global_len).grid(row=1, column=1)
tk.Label(self.root, text='width:').grid(row=2, column=0, sticky='e')
tk.Label(self.root, text=global_width).grid(row=2, column=1)
tk.Label(self.root, text='mines:').grid(row=3, column=0, sticky='e')
tk.Label(self.root, text=global_mines).grid(row=3, column=1)
tk.Button(self.root, text="OK", command=self.root.destroy).grid(row=4, column=0, columnspan=2)
self.root.mainloop()
# --- main ---
# default value at start
global_len = '0'
global_width = '0'
global_mines = '0'
while True:
GetDataWindow()
MainFieldWindow()
#win = GetDataWindow()
#del win
#win = MainWindow()
#del win
# create and hide main window before creating message
root = tk.Tk()
root.withdraw()
res = messagebox.askyesno("Game Over", message="Play again?")
if not res:
break
root.destroy()
顺便说一句:
当然可以不用关键字global
,比如:
len_ = 0
width = 0
mines = 0
while True:
win = GetDataWindow(len_, width, mines)
len_ = win.len_
width = win.width
mines = win.mines
MainWindow(len_, width, mines)
# ... the rest ...
或更简单:
settings = {
'len': 0,
'width': 0,
'mines': 0,
}
while True:
GetDataWindow(settings)
MainWindow(settings)
# ... the rest ...
但是我跳过了这部分。
我也可以使用 IntVar
而不是 StringVar
。