为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

喵喔喔 2023-04-18 15:03:53
我想制作一个页面,右边有一些标签,左边有一些其他标签及其各自的滚动条。但我没能做到。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()如果您测试此代码,您会发现存在问题。你能帮我吗 ?先感谢您。
查看完整描述

3 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

首先你不应该执行以下两行:


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

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

因为您不应该使用grid()orpack()或将小部件放入画布中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()



查看完整回答
反对 回复 2023-04-18
?
catspeake

TA贡献1111条经验 获得超0个赞

检查我的答案:

按照以下步骤scroll widget操作canvas

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


查看完整回答
反对 回复 2023-04-18
?
慕斯王

TA贡献1864条经验 获得超2个赞

此更正解决了问题。玩它。还学习如何使用 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()


查看完整回答
反对 回复 2023-04-18
  • 3 回答
  • 0 关注
  • 199 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号