【问题标题】:Tkinter Spinbox Widget Changing Size When Switching Between FramesTkinter Spinbox 小部件在帧之间切换时更改大小
【发布时间】:2015-08-12 01:23:55
【问题描述】:

我正在创建一个 Tkinter 应用程序,该应用程序在 GUI 中有一个框架,根据用户在程序中所做的更改而有所不同。它似乎可以在显示哪个帧之间切换。但是,每次返回到它所在的框架时,旋转框小部件都会改变其大小。我尝试使用 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 上的虚拟机)- 工作得很好。

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

【问题讨论】:

  • 不知何故,我系统上的小部件在切换框架后不会改变大小。您的 Spinbox 是如何变化的?是变大还是变小?
  • 它越来越小了。当我运行它时,看起来宽度好像变小了。最终它会完全消失。此外,标签“订单:”似乎被某些东西(可能不再可见的小部件?)覆盖并且也消失了。
  • 似乎适用于我的系统(windows 7 64bit,Python 2.7)
  • 我刚刚在 Windows XP 上尝试过,它可以工作。但它不适用于我的任何 Mac。 mac 上的 tkinter 可能存在错误?

标签: python user-interface tkinter widget


【解决方案1】:

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

我可以通过移除除可见框架之外的所有框架(使用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()

【讨论】:

  • 感谢您的帮助!我还发现了另一个涉及更改relief=borderwidth= 参数的修复程序。但是,它会降低旋转框的吸引力。
【解决方案2】:

我设法通过更改一些参数找到了解决此问题的另一种方法。如果您更改 relife=borderwidth= 参数,微调框将正常运行。这种方法的唯一缺点是小部件在 GUI 中看起来不合适,而且看起来不太吸引人。

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

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

【讨论】:

    猜你喜欢
    • 2011-03-02
    • 2020-10-10
    • 2017-10-18
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多