【问题标题】:Tkinter Side BarTkinter 侧边栏
【发布时间】:2021-06-25 17:14:59
【问题描述】:

我想创建一个类似于 ABOVE 的可折叠侧栏。
在折叠的表单中,侧栏将只有选项图标,当您将鼠标悬停在栏上时,它会展开,向您显示图标的描述/名称。
如果您单击该图标,它将带您进入该图标指定的功能,例如设置页面。
在右侧,我将看到带有很多按钮的主页。
我不知道你会怎么做,所以请帮我开始,我应该处理剩下的。
是否也可以仅使用基本的 Tkinter 来执行此操作,或者我是否需要通过 pip 导入更多模块(不推荐)
到目前为止,我有这个:

def loginnow(name):
global login
login.destroy()
login= Tk()
screen_width = login.winfo_screenwidth()
screen_height = login.winfo_screenheight()
screen_height=str(screen_height)
screen_width=str(screen_width)
screen = screen_width+"x"+screen_height
login.geometry(screen)
login.title("Logged in as %s"%name)

侧边栏将包括 设置 = https://www.iconpacks.net/icons/2/free-settings-icon-3110-thumb.png
一旦我得到一个大致的想法,我将使用其他图标进行管理。
我希望菜单可见,而无需单击某些内容即可显示。

【问题讨论】:

  • 可以,但是有没有办法像在 GIF 中那样,没有 3 行下拉菜单?
  • 哪三行,下拉菜单。
  • 在视频上,Tkinter 导航栏左上角 |使用 Python Tkinter 的酷导航栏
  • 是的,你可以,也许bind 整件事都交给<Enter><Leave>

标签: python tkinter sidebar


【解决方案1】:

解释:

这实际上可以通过使用绑定来实现。看看下面这个粗略的例子:
from tkinter import *
from PIL import Image, ImageTk

root = Tk()
root.geometry('600x600')

min_w = 50 # Minimum width of the frame
max_w = 200 # Maximum width of the frame
cur_width = min_w # Increasing width of the frame
expanded = False # Check if it is completely exanded

def expand():
    global cur_width, expanded
    cur_width += 10 # Increase the width by 10
    rep = root.after(5,expand) # Repeat this func every 5 ms
    frame.config(width=cur_width) # Change the width to new increase width
    if cur_width >= max_w: # If width is greater than maximum width 
        expanded = True # Frame is expended
        root.after_cancel(rep) # Stop repeating the func
        fill()

def contract():
    global cur_width, expanded
    cur_width -= 10 # Reduce the width by 10 
    rep = root.after(5,contract) # Call this func every 5 ms
    frame.config(width=cur_width) # Change the width to new reduced width
    if cur_width <= min_w: # If it is back to normal width
        expanded = False # Frame is not expanded
        root.after_cancel(rep) # Stop repeating the func
        fill()

def fill():
    if expanded: # If the frame is exanded
        # Show a text, and remove the image
        home_b.config(text='Home',image='',font=(0,21))
        set_b.config(text='Settings',image='',font=(0,21))
        ring_b.config(text='Bell Icon',image='',font=(0,21))
    else:
        # Bring the image back
        home_b.config(image=home,font=(0,21))
        set_b.config(image=settings,font=(0,21))
        ring_b.config(image=ring,font=(0,21))

# Define the icons to be shown and resize it
home = ImageTk.PhotoImage(Image.open('home.png').resize((40,40),Image.ANTIALIAS))
settings = ImageTk.PhotoImage(Image.open('settings.png').resize((40,40),Image.ANTIALIAS))
ring = ImageTk.PhotoImage(Image.open('ring.png').resize((40,40),Image.ANTIALIAS))

root.update() # For the width to get updated
frame = Frame(root,bg='orange',width=50,height=root.winfo_height())
frame.grid(row=0,column=0) 

# Make the buttons with the icons to be shown
home_b = Button(frame,image=home,bg='orange',relief='flat')
set_b = Button(frame,image=settings,bg='orange',relief='flat')
ring_b = Button(frame,image=ring,bg='orange',relief='flat')

# Put them on the frame
home_b.grid(row=0,column=0,pady=10)
set_b.grid(row=1,column=0,pady=50)
ring_b.grid(row=2,column=0)

# Bind to the frame, if entered or left
frame.bind('<Enter>',lambda e: expand())
frame.bind('<Leave>',lambda e: contract())

# So that it does not depend on the widgets inside the frame
frame.grid_propagate(False)

root.mainloop()

我已经使用 cmets 解释了代码,以便随时随地理解。图标取自Flat Icons。可以看出,它有其自身的缺点,但您可以通过它模仿更接近您所展示的东西。您可以通过创建自定义小部件以在展开时同时保存图标和文本等方式来进一步改善这一点。

输出:

更新图片代码(不含PIL):

home = PhotoImage(file='home.png') # Make sure the image size is comparable to the minimum frame width
settings = PhotoImage(file='settings.png')
ring = PhotoImage(file='ring.png')

【讨论】:

  • 这就是我想要的,但是没有 PIL 你能做到吗?
  • @Bond007 您需要 PIL 将图像大小调整为 25x25 或确保您的图标为 25x25 像素,然后使用更新后的代码。
  • 好的,谢谢大家的帮助,一定会用这个
【解决方案2】:

虽然 tkinter 没有这样的内置功能,但您拥有实现它的所有工具。首先创建一个框架来容纳侧边栏,然后绑定到框架上的&lt;Enter&gt;&lt;Leave&gt; 事件以显示和隐藏它。

至少有三种方法可以显示和隐藏它。例如,如果每个项目都是一个带有图像和文本的按钮,并使用 pack 添加到框架中,您可以简单地添加或删除按钮的文本部分以使其缩小或示例。

或者,如果使用grid 并将图标和文本创建为单独的小部件,您可以使用grid_remove 删除第二列中的所有内容,从而导致框架缩小。

或者,您可以使用place 将侧边栏添加到根窗口,并使用place 更改显示或隐藏框架的宽度。

【讨论】:

  • 也感谢您的帮助。
猜你喜欢
  • 2019-09-20
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多