Tkinter Spinbox 小部件在帧之间切换时更改大小
Tkinter Spinbox Widget Changing Size When Switching Between Frames
我正在创建一个 Tkinter 应用程序,它在 GUI 中有一个框架,它的变化取决于用户在程序中所做的事情。就在显示哪个帧之间切换而言,它似乎有效。但是,每次返回到它所在的框架时,spinbox 小部件都会更改其大小。我尝试使用 width=5
的固定宽度,但仍然遇到同样的问题。我还尝试使用 pack()
而不是 grid()
。是什么导致它改变形状,我该如何阻止它?
import tkinter as tk
from tkinter import ttk
class ODE_Solver_App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
equation_settings = ttk.Frame(self)
equation_settings.pack(side="top", fill="both", expand = True)
equation_settings.grid_rowconfigure(0, weight=1)
equation_settings.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (ODE_Equation_Settings, System_Equation_Settings):
frame = F(equation_settings, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(ODE_Equation_Settings)
# Buttons in the main class for switching between frames.
button1 = tk.Button(self, text="ODE Settings", command=lambda: self.show_frame(ODE_Equation_Settings))
button1.pack()
button2 = tk.Button(self, text="System Settings", command=lambda: self.show_frame(System_Equation_Settings))
button2.pack()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class ODE_Equation_Settings(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
equation_profile = tk.Frame(self) # I am going to have more frames in this class.
equation_profile.pack()
order_label = tk.Label(equation_profile, text="Order:")
order_label.grid(row=0, column=0, sticky="w")
order_select = tk.Spinbox(equation_profile, width=5, from_=1, to=100000) # This is the spinbox that is changing in size.
order_select.grid(row=0, column=1, sticky="e")
class System_Equation_Settings(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="This is Another Page!")
label.pack(pady=10,padx=10)
button1 = tk.Button(self, text="This does nothing yet...")
button1.pack()
app = ODE_Solver_App()
app.mainloop()
我在 Yosemite
上使用 Python 3.4
编辑:
我在不同的计算机上尝试了 运行 该程序。结果如下:
Mac OS Mavericks - 同样的问题。
Windows XP(虚拟 machine on mac)- 工作正常。
问题似乎与我正在使用的OS有关。
我认为这是 OSX 版 Tkinter 中的错误。众所周知,它有点问题。我注意到,如果我调整 window 的大小——即使只是调整一个像素——旋转框也会恢复。这似乎是渲染系统中的一个小故障。
我可以通过移除除可见帧之外的所有帧(使用 grid_forget
)然后重新网格化应该可见的帧来获得更好的结果,而不是升高和降低帧。但是,我仍然看到异常现象,只有在我摇动鼠标后才会消失。不过,调用 update_idletasks()
作为 show_frame
的最后一步似乎可以解决这个问题。
您可以试试下面的代码,看看它是否更适合您。每次切换帧时它都会调整 window 的大小,尽管您可以通过给主要 window 一个足够大以容纳任一帧的固定大小来解决这个问题。
def show_frame(self, cont):
for frame in self.frames:
self.frames[frame].grid_forget()
frame = self.frames[cont]
self.frames[cont].grid()
frame.update_idletasks()
我设法通过更改一些参数找到了另一种解决问题的方法。如果更改 relife=
或 borderwidth=
参数,旋转框将正常运行。这种方法的唯一缺点是小部件在 GUI 中看起来不合适,看起来不太吸引人。
但是,还有第二种方法涉及将旋转框作为 ttk 小部件。 ttk 没有这个小部件,所以你需要制作它。 This post here 向您展示了如何做到这一点。这是一个很好的修复,尤其是当您担心 GUI 的外观时。
*注意:这个问题似乎是 Mac 的 tkinter 中的错误。到目前为止,原始 post 中的代码在 Windows.
上运行良好
我正在创建一个 Tkinter 应用程序,它在 GUI 中有一个框架,它的变化取决于用户在程序中所做的事情。就在显示哪个帧之间切换而言,它似乎有效。但是,每次返回到它所在的框架时,spinbox 小部件都会更改其大小。我尝试使用 width=5
的固定宽度,但仍然遇到同样的问题。我还尝试使用 pack()
而不是 grid()
。是什么导致它改变形状,我该如何阻止它?
import tkinter as tk
from tkinter import ttk
class ODE_Solver_App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
equation_settings = ttk.Frame(self)
equation_settings.pack(side="top", fill="both", expand = True)
equation_settings.grid_rowconfigure(0, weight=1)
equation_settings.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (ODE_Equation_Settings, System_Equation_Settings):
frame = F(equation_settings, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(ODE_Equation_Settings)
# Buttons in the main class for switching between frames.
button1 = tk.Button(self, text="ODE Settings", command=lambda: self.show_frame(ODE_Equation_Settings))
button1.pack()
button2 = tk.Button(self, text="System Settings", command=lambda: self.show_frame(System_Equation_Settings))
button2.pack()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class ODE_Equation_Settings(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
equation_profile = tk.Frame(self) # I am going to have more frames in this class.
equation_profile.pack()
order_label = tk.Label(equation_profile, text="Order:")
order_label.grid(row=0, column=0, sticky="w")
order_select = tk.Spinbox(equation_profile, width=5, from_=1, to=100000) # This is the spinbox that is changing in size.
order_select.grid(row=0, column=1, sticky="e")
class System_Equation_Settings(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="This is Another Page!")
label.pack(pady=10,padx=10)
button1 = tk.Button(self, text="This does nothing yet...")
button1.pack()
app = ODE_Solver_App()
app.mainloop()
我在 Yosemite
上使用 Python 3.4编辑: 我在不同的计算机上尝试了 运行 该程序。结果如下: Mac OS Mavericks - 同样的问题。 Windows XP(虚拟 machine on mac)- 工作正常。
问题似乎与我正在使用的OS有关。
我认为这是 OSX 版 Tkinter 中的错误。众所周知,它有点问题。我注意到,如果我调整 window 的大小——即使只是调整一个像素——旋转框也会恢复。这似乎是渲染系统中的一个小故障。
我可以通过移除除可见帧之外的所有帧(使用 grid_forget
)然后重新网格化应该可见的帧来获得更好的结果,而不是升高和降低帧。但是,我仍然看到异常现象,只有在我摇动鼠标后才会消失。不过,调用 update_idletasks()
作为 show_frame
的最后一步似乎可以解决这个问题。
您可以试试下面的代码,看看它是否更适合您。每次切换帧时它都会调整 window 的大小,尽管您可以通过给主要 window 一个足够大以容纳任一帧的固定大小来解决这个问题。
def show_frame(self, cont):
for frame in self.frames:
self.frames[frame].grid_forget()
frame = self.frames[cont]
self.frames[cont].grid()
frame.update_idletasks()
我设法通过更改一些参数找到了另一种解决问题的方法。如果更改 relife=
或 borderwidth=
参数,旋转框将正常运行。这种方法的唯一缺点是小部件在 GUI 中看起来不合适,看起来不太吸引人。
但是,还有第二种方法涉及将旋转框作为 ttk 小部件。 ttk 没有这个小部件,所以你需要制作它。 This post here 向您展示了如何做到这一点。这是一个很好的修复,尤其是当您担心 GUI 的外观时。
*注意:这个问题似乎是 Mac 的 tkinter 中的错误。到目前为止,原始 post 中的代码在 Windows.
上运行良好