首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有标签、帆布和框架的Tkinter滚动条

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

Stack Overflow用户
提问于 2020-07-31 12:02:12
回答 3查看 267关注 0票数 0

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

代码语言:javascript
复制
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()

如果测试这段代码,就会发现存在问题。你能帮帮我吗?提前谢谢你。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-07-31 13:33:42

核对我的答案:

scroll widget on canvas 遵循以下步骤:

创建框架1,这将包含画布和scrollbar

  • Create框架2,这将在画布上滚动,您可以在此框架上网格任何小部件,但您需要使用canvas.create_window.

创建窗口。

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

代码语言:javascript
复制
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()
票数 2
EN

Stack Overflow用户

发布于 2020-07-31 13:33:15

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

代码语言:javascript
复制
frameL.grid(row=0, column=0, sticky="news")
frameR.grid(row=0, column=0, sticky="news")

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

第二,两个滚动条的父值应该是root,而不是:

代码语言:javascript
复制
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")

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

代码语言:javascript
复制
frameL.grid_propagate(False)
frameR.grid_propagate(False)

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

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

代码语言:javascript
复制
root.update()
canvasL.configure(scrollregion=canvasL.bbox("all"))
canvasR.configure(scrollregion=canvasR.bbox("all"))

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

代码语言:javascript
复制
frameL.bind('<Configure>', lambda e: canvasL.config(scrollregion=canvasL.bbox('all')))
frameR.bind('<Configure>', lambda e: canvasR.config(scrollregion=canvasR.bbox('all')))

下面是一个基于您的示例的修改示例:

代码语言:javascript
复制
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()
票数 3
EN

Stack Overflow用户

发布于 2020-07-31 12:40:34

这种修正解决了这个问题。玩玩它。还学习如何使用ttk美化GUI

代码语言:javascript
复制
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()
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63191477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档