【问题标题】:How do you size a tkinter frame dynamically你如何动态调整 tkinter 框架的大小
【发布时间】:2018-10-09 05:31:15
【问题描述】:

我有一个框架我想用作侧边栏导航菜单。我希望菜单可以用鼠标调整大小。我有调整框架大小的代码,但在调整顶层窗口大小之前它不会调整大小。我知道 PanedWindows,这对我不起作用。

from tkinter import *


def dragbar_on_click(event):
    event.widget.mouse_x = event.x


def dragbar_on_release(event):
    event.widget.mouse_x = 0


def dragbar_on_motion(event):
    if event.widget.mouse_x != 0:
        width = event.widget.parent.winfo_width() + event.x - event.widget.mouse_x

        event.widget.parent.config(width=width)


class DragBar(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent


class SideMenu(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        self.config(bg='red', width=300)
        self.rowconfigure(0, weight=1)
        self.grid(sticky='NSEW')
        self.grid_propagate(0)

        self.frame = Frame(self, bg='purple')
        self.columnconfigure(0, weight=1)
        self.frame.grid(row=0, column=0, sticky='NSEW')

        self.dragbar = DragBar(self, bg='green', width=10)
        self.dragbar.mouse_x = 0
        self.dragbar.grid(row=0, column=1, sticky='NSW')

        self.dragbar.bind("<Motion>", dragbar_on_motion)
        self.dragbar.bind("<Button-1>", dragbar_on_click)
        self.dragbar.bind("<ButtonRelease-1>", dragbar_on_release)


root = Tk()
root.rowconfigure(0, weight=1)
root.columnconfigure(1, weight=1)

f = SideMenu(root)
Label(f.frame, text='This is a test line.').grid(sticky='NW')

root.mainloop()

【问题讨论】:

  • 听起来你想使用PanedWindow,对吗?
  • 我知道 PanedWindows,但它不适用于我正在进行的当前项目。谢谢你的建议。
  • 我不明白您的要求有何不同。似乎您想要两个并排的小部件和一个可移动的屏障,可用于使一侧更大而另一侧更小。
  • 是的,但是如果我将侧边菜单放在左窗格中,则菜单将位于窗格窗口中。当我更改窗口时,我只是隐藏内容窗格并覆盖一个新的。这意味着我需要为每一帧重新填充菜单。我包含了另一个视频,显示了使用窗格来保存侧菜单时出现的问题。我希望这能帮助您更好地理解我的问题.... 视频:youtu.be/RW7Fao4aZ70
  • 对不起,我还是不明白。我在左侧看到一个导航面板。我不明白你为什么要复制它。您可以拥有一个左侧导航面板,然后是一个右侧面板,其中包含您想要的任何内容——包括其他面板。您可以切换右侧,而无需在左侧重新创建任何内容。

标签: python python-3.x tkinter


【解决方案1】:

我不能 100% 确定是否有更好的方法,但看起来滑块会在 "&lt;Configure&gt;" 事件触发时更新。

所以这里有一个快速的hacky方法。

在您的函数dragbar_on_motion 中添加以下行:

x = root.winfo_width()
y = root.winfo_height()
root.geometry("{}x{}".format(x, y))

这将强制触发"&lt;Configure&gt;" 事件并更新滑块。

这里是你的代码修改:

from tkinter import *


def dragbar_on_click(event):
    event.widget.mouse_x = event.x


def dragbar_on_release(event):
    event.widget.mouse_x = 0

def dragbar_on_motion(event):
    if event.widget.mouse_x != 0:
        width = event.widget.parent.winfo_width() + event.x - event.widget.mouse_x
        event.widget.parent.config(width=width)
        x = root.winfo_width()
        y = root.winfo_height()
        root.geometry("{}x{}".format(x, y))

class DragBar(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent


class SideMenu(Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)

        self.config(bg='red', width=300)
        self.rowconfigure(0, weight=1)
        self.grid(sticky='NSEW')
        self.grid_propagate(0)

        self.frame = Frame(self, bg='purple')
        self.columnconfigure(0, weight=1)
        self.frame.grid(row=0, column=0, sticky='NSEW')

        self.dragbar = DragBar(self, bg='green', width=10)
        self.dragbar.mouse_x = 0
        self.dragbar.grid(row=0, column=1, sticky='NSW')

        self.dragbar.bind("<Motion>", dragbar_on_motion)
        self.dragbar.bind("<Button-1>", dragbar_on_click)
        self.dragbar.bind("<ButtonRelease-1>", dragbar_on_release)


root = Tk()
root.rowconfigure(0, weight=1)
root.columnconfigure(1, weight=1)

f = SideMenu(root)
Label(f.frame, text='This is a test line.').grid(sticky='NW')

root.mainloop()

【讨论】:

  • 什么意思?对我来说,这允许在不移动窗口的情况下即时调整大小。
  • 我确实像你说的那样将代码添加到了 dragbar_on_motion 方法中,但它什么也没做。
  • 我刚刚尝试过,但由于某种原因它对我不起作用。我正在重构我的代码,以便我可以使用 PanedWindow,感谢 Mike 的帮助。
  • @DanielHuckson 你用的是什么版本的python?
  • 我使用的是 Python 3.6 版
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多