带有标签、画布和框架的Tkinter滚动条

2024-06-28 20:36:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我想做一个页面,右边有一些标签,左边有一些其他标签和它们各自的滚动条。但我没能做到

from tkinter import *

root = Tk()

root.columnconfigure(0, weight=1)
root.columnconfigure(2, weight=1)

canvasL = Canvas(root, bg='blue')
canvasL.grid(row=0, column=0, sticky="news")

canvasR = Canvas(root, bg='blue')
canvasR.grid(row=0, column=2, sticky="news")

frameL = Frame(canvasL, bg='red', width=1000)
frameL.grid(row=0, column=0, sticky="news")

frameR = Frame(canvasR, bg='red')
frameR.grid(row=0, column=0, sticky="news")

frameL.grid_propagate(False)
frameR.grid_propagate(False)

S1 = Scrollbar(frameL, orient="vertical", command=canvasL.yview)
S1.grid(row=0, column=1, sticky="news")

S2 = Scrollbar(frameR, orient="vertical", command=canvasR.yview)
S2.grid(row=0, column=3, sticky="news")

canvasL.configure(yscrollcommand=S1.set)
canvasL.configure(scrollregion=canvasL.bbox("all"))

canvasR.configure(yscrollcommand=S2.set)
canvasR.configure(scrollregion=canvasR.bbox("all"))

canvasL.create_window((0, 0), anchor='nw', window=frameL)
canvasR.create_window((0, 0), anchor='nw', window=frameR)

for i in range(0, 40):
    labelName = Label(frameL, text="Name : " + str(i), bg='#F5F5F5')
    labelName.grid(row=i, column=0)
    labelName = Label(frameR, text="Name : " + str(i), bg='#F5F5F5')
    labelName.grid(row=i, column=2)

root.mainloop()

如果您测试这段代码,就会发现有问题。你能帮我吗? 先谢谢你


Tags: configurecolumnrootwindowgridrownewsbg
3条回答

检查我的答案:

对于canvas上的scroll widget,请按照以下步骤操作:

  1. 创建第1帧,这将保存画布和滚动条
  2. 创建将在画布上滚动的第2帧,您可以在此帧上网格化任何小部件 但您需要使用canvas.create_window创建窗口

你们可以在评论中讨论额外的问题

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.geometry('800x400+0+0')
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
root.rowconfigure(0, weight=1)

########################################################################
######## Left Side ####################################################
left_container = tk.Frame(root, bg='green')
left_container.grid(row=0, column=0, sticky='nsew', padx=(0, 2))
left_container.columnconfigure(0, weight=1)
left_container.rowconfigure(0, weight=1)

left_canvas = tk.Canvas(left_container, bg='orange')
left_canvas.grid(row=0, column=0, sticky='nsew')

left_scrollbar = tk.Scrollbar(left_container, orient='vertical', command=left_canvas.yview)
left_scrollbar.grid(row=0, column=1, sticky='nsew')
left_canvas['yscrollcommand'] = left_scrollbar.set

left_canvas.columnconfigure(0, weight=1)
left_canvas.rowconfigure(0, weight=1)

left_final_window = tk.Frame(left_canvas, bg='green')
left_canvas.create_window((0, 0), window=left_final_window, anchor='nw', tags='expand1')
left_final_window.columnconfigure(0, weight=1)

for i in range(1, 51):
    label = tk.Label(left_final_window, text=f'Manish Pushpam ({i})')
    label.grid(row=i-1, column=0, sticky='nsew', pady=(0, 2))


left_canvas.bind('<Configure>', lambda event: left_canvas.itemconfigure('expand1', width=event.width))
left_final_window.update_idletasks()
left_canvas.config(scrollregion=left_canvas.bbox('all'))
############### Scroll Using Mouse Wheel ###############
def scroll(event, widget):
    widget.yview_scroll(int(-1 * (event.delta / 120)), "units")


def final_scroll(event, widget, func):
    widget.bind_all("<MouseWheel>", func)


def stop_scroll(event, widget):
    widget.unbind_all("<MouseWheel>")


left_canvas.bind("<Enter>", lambda event: final_scroll(event, left_canvas, lambda event: scroll(event, left_canvas)))
left_canvas.bind("<Leave>", lambda event: stop_scroll(event, left_canvas))
########################################################################
######## Right Side ####################################################
right_container = tk.Frame(root, bg='orange')
right_container.grid(row=0, column=1, sticky='nsew')
right_container.columnconfigure(0, weight=1)
right_container.rowconfigure(0, weight=1)

right_canvas = tk.Canvas(right_container, bg='red')
right_canvas.grid(row=0, column=0, sticky='nsew')

right_scrollbar = tk.Scrollbar(right_container, orient='vertical', command=right_canvas.yview)
right_scrollbar.grid(row=0, column=1, sticky='nsew')
right_canvas['yscrollcommand'] = right_scrollbar.set

right_canvas.columnconfigure(0, weight=1)
right_canvas.rowconfigure(0, weight=1)

right_final_window = tk.Frame(right_canvas, bg='green')
right_canvas.create_window((0, 0), window=right_final_window, anchor='nw', tags='expand')
right_final_window.columnconfigure(0, weight=1)

for i in range(1, 51):
    label = tk.Label(right_final_window, text=f'Manish Pushpam ({i})')
    label.grid(row=i-1, column=0, sticky='nsew', pady=(0, 2))

right_canvas.bind_all('<Configure>', lambda event: right_canvas.itemconfigure('expand', width=event.width))
right_final_window.update_idletasks()
right_canvas.config(scrollregion=right_canvas.bbox('all'))

right_canvas.bind("<Enter>", lambda event: final_scroll(event, right_canvas, lambda event: scroll(event, right_canvas)))
right_canvas.bind("<Leave>", lambda event: stop_scroll(event, right_canvas))
root.mainloop()

这一修正解决了问题。玩它。还要学习如何使用ttk来美化您的GUI



from tkinter import *

root = Tk()

root.columnconfigure(0, weight=1)
root.columnconfigure(2, weight=1)

canvasL = Canvas(root, bg='blue')
canvasL.grid(row=0, column=0, sticky="news")

canvasR = Canvas(root, bg='blue')
canvasR.grid(row=0, column=2, sticky="news")

frameL = Frame(canvasL, bg='red', width=1000)
frameL.grid(row=0, column=0, sticky="news")

frameR = Frame(canvasR, bg='red')
frameR.grid(row=0, column=0, sticky="news")

frameL.grid_propagate(False)
frameR.grid_propagate(False)

S1 = Scrollbar(frameL, orient="vertical", command=canvasL.yview)
S1.grid(row=0, column=1, sticky="news")

S2 = Scrollbar(frameR, orient="vertical", command=canvasR.yview)
S2.grid(row=0, column=3, sticky="news")

canvasL.configure(yscrollcommand=S1.set)
canvasL.configure(scrollregion=canvasL.bbox("all"))

canvasR.configure(yscrollcommand=S2.set)
canvasR.configure(scrollregion=canvasR.bbox("all"))

canvasL.create_window((0, 0), anchor='nw', window=frameL)
canvasR.create_window((0, 0), anchor='nw', window=frameR)

for i in range(0, 40):
#use the cavasL and canvasR directly, they are at the closer to #the root
    labelName = Label(canvasL, text="Name : " + str(i), bg='#F5F5F5')
    labelName.grid(row=i, column=0)
    labelName = Label(canvasR, text="Name : " + str(i), bg='#F5F5F5')
    labelName.grid(row=i, column=2)

root.mainloop()

首先,不应执行以下两行:

frameL.grid(row=0, column=0, sticky="news")
frameR.grid(row=0, column=0, sticky="news")

因为您不应该使用grid()pack()place()将小部件放入画布。然后你用create_window(...)把它们放到画布上

第二,两个滚动条的父级应该是root

S1 = Scrollbar(root, orient="vertical", command=canvasL.yview)
S1.grid(row=0, column=1, sticky="ns")

S2 = Scrollbar(root, orient="vertical", command=canvasR.yview)
S2.grid(row=0, column=3, sticky="ns")

此外,也不应执行以下两行:

frameL.grid_propagate(False)
frameR.grid_propagate(False)

因为它们可能使两个框架的高度为零

最后,在调用root.update()之后,您必须调用以下两行:

root.update()
canvasL.configure(scrollregion=canvasL.bbox("all"))
canvasR.configure(scrollregion=canvasR.bbox("all"))

但最好在调整帧大小时更新scrollregion

frameL.bind('<Configure>', lambda e: canvasL.config(scrollregion=canvasL.bbox('all')))
frameR.bind('<Configure>', lambda e: canvasR.config(scrollregion=canvasR.bbox('all')))

以下是基于您的修改示例:

from tkinter import *

root = Tk()

root.columnconfigure(0, weight=1)
root.columnconfigure(2, weight=1)

canvasL = Canvas(root, bg='blue', highlightthickness=0)
canvasL.grid(row=0, column=0, sticky="news")

canvasR = Canvas(root, bg='blue', highlightthickness=0)
canvasR.grid(row=0, column=2, sticky="news")

frameL = Frame(canvasL, bg='red', width=1000)
#frameL.grid(row=0, column=0, sticky="news")

frameR = Frame(canvasR, bg='red')
#frameR.grid(row=0, column=0, sticky="news")

#frameL.grid_propagate(False)
#frameR.grid_propagate(False)

S1 = Scrollbar(root, orient="vertical", command=canvasL.yview)
S1.grid(row=0, column=1, sticky="ns")

S2 = Scrollbar(root, orient="vertical", command=canvasR.yview)
S2.grid(row=0, column=3, sticky="ns")

canvasL.configure(yscrollcommand=S1.set)
canvasR.configure(yscrollcommand=S2.set)

canvasL.create_window((0, 0), anchor='nw', window=frameL)
canvasR.create_window((0, 0), anchor='nw', window=frameR)

for i in range(0, 40):
    labelName = Label(frameL, text="Name : " + str(i), bg='#F5F5F5')
    labelName.grid(row=i, column=0)
    labelName = Label(frameR, text="Name : " + str(i), bg='#F5F5F5')
    labelName.grid(row=i, column=2)

root.update()
canvasL.configure(scrollregion=canvasL.bbox("all"))
canvasR.configure(scrollregion=canvasR.bbox("all"))

# better update scrollregion upon resize of frame
#frameL.bind('<Configure>', lambda e: canvasL.config(scrollregion=canvasL.bbox('all')))
#frameR.bind('<Configure>', lambda e: canvasR.config(scrollregion=canvasR.bbox('all')))

root.mainloop()

相关问题 更多 >