Tkinter Spinbox小部件在帧之间切换时改变大小

时间:2015-08-11 04:34:52

标签: python user-interface tkinter widget

我正在创建一个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(Mac上的虚拟机) - 工作正常。

好像问题与我正在使用的操作系统有关。

2 个答案:

答案 0 :(得分:2)

我认为这是Tkinter的OSX版本中的一个错误。众所周知,它有点儿麻烦。我注意到如果我调整窗口大小 - 即使只是一个像素 - 旋转盒也会恢复。这似乎是渲染系统中的一个小故障。

我可以通过删除除可见帧(使用grid_forget)之后的所有帧然后重新网格化应该可见的帧而不是升高和降低帧来获得更好的结果。但是,我仍然看到一个异常,只有在我摇动鼠标后才会消失。但是,将update_idletasks()作为show_frame中的最后一步,似乎会让问题消失。

您可以尝试以下代码,看看它是否适合您。每次切换帧时都会产生调整窗口大小的副作用,不过你可以通过给主窗口一个足够大的固定大小来控制它来控制它。

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

答案 1 :(得分:0)

我设法找到另一种方法来改变一些参数来解决这个问题。如果您更改relife=borderwidth=参数,则旋转框的行为正常。这种方法的唯一缺点是窗口小部件在GUI中看起来不合适,并且看起来不太吸引人。

然而,还有第二种方法涉及使spinbox成为ttk小部件。 ttk没有这个小部件,所以你需要制作它。 This post here向您展示了如何做到这一点。这是一个很好的解决方案,特别是如果您关心GUI的外观。

*注意:此问题似乎是适用于Mac的tkinter中的错误。到目前为止,原始帖子中的代码在Windows上运行良好。