You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter中Scrollbar不显示、无法填充y轴的问题求助

Tkinter Canvas滚动条失效/显示异常问题修复

问题根源

代码存在3个核心错误,直接导致滚动条无法正常工作:

  1. 布局顺序错误:先调用allTelemetryCanvas.pack(fill="both", expand=1)让Canvas占满了父Frame全部空间,后续再pack右侧滚动条时,没有剩余空间分配给滚动条,就会出现滚动条不可见、高度无法填满的问题。
  2. 滚动区域未更新:直接将Label、Entry等控件通过grid()放在Canvas上,Canvas不会自动计算这些子控件的总尺寸,scrollregion默认值为0,滚动条没有可滚动的范围,自然无法拖动。
  3. 控件挂载方式错误:Canvas本身不是容器类组件,不能直接作为其他控件的父容器承载布局,需要先在Canvas中嵌入一个独立Frame,把所有表格控件放在这个内部Frame里,再通过Canvas的窗口对象管理这个Frame。

修复步骤

  • 调整pack顺序:先pack右侧垂直滚动条,再pack Canvas,保证滚动条优先获得右侧宽度空间
  • 新增承载所有表格内容的内部Frame,通过allTelemetryCanvas.create_window()把这个Frame嵌入Canvas
  • 给内部Frame绑定<Configure>事件,当内部Frame尺寸变化时,自动更新Canvas的scrollregion参数,让滚动条匹配实际内容高度
  • 可选增加Canvas宽度自适应、鼠标滚轮滚动支持,优化使用体验

修复后可运行代码

from tkinter import *
from tkinter import ttk

root = Tk()
root.state('zoomed')

# creating notebook
telemetry = ttk.Notebook(root, width=1083, height=200)
telemetry.place(x=440, y=560)

allTelemetry = Frame(telemetry)
allTelemetry.pack(fill="both", expand = 1)

# 先创建滚动条并优先pack,避免被Canvas挤掉空间
scrollbar = ttk.Scrollbar(allTelemetry, orient='vertical')
scrollbar.pack(side=RIGHT, fill="y")

# creating canvas for scrollbar 
allTelemetryCanvas = Canvas(allTelemetry, yscrollcommand=scrollbar.set)
allTelemetryCanvas.pack(fill="both", expand = 1)
scrollbar.config(command=allTelemetryCanvas.yview)

# 创建Canvas内部承载内容的Frame
content_frame = Frame(allTelemetryCanvas)
# 将内部Frame嵌入Canvas
canvas_window = allTelemetryCanvas.create_window((0,0), window=content_frame, anchor='nw')

# 内容尺寸变化时自动更新滚动区域
def update_scrollregion(event):
    allTelemetryCanvas.configure(scrollregion=allTelemetryCanvas.bbox("all"))
content_frame.bind("<Configure>", update_scrollregion)

# 让内部Frame宽度随Canvas宽度自适应
def fit_canvas_width(event):
    allTelemetryCanvas.itemconfig(canvas_window, width=event.width)
allTelemetryCanvas.bind("<Configure>", fit_canvas_width)

dotTelemetry = Frame(telemetry)
dotTelemetry.pack(fill="both", expand = 1)

telemetry.add(allTelemetry, text= u"Hepsini Goster")
telemetry.add(dotTelemetry, text= u"Anlik Telemetri")

#------------------------------------------------------------
teleTitle = [" ", "Takmno","Paketno","Zaman",
        "1Basn","2Basn",
        "Nem",
        "1kseklik","2Ykseklik",
        "rtifaFark","niHz","Scaklk","PilGerilimi",
        "La1","Lo1","Al1",
        "La2","Lo2","Al2",
        "Drm",
        "x","y","z",
        "DnSays","Video"]

# 所有内容控件放在content_frame而非Canvas上
empty = Label(content_frame, text="",width=3)
empty.grid(row=0,column=0,padx=1, pady=1)
for j in range(1,25):
    teleTitle[j] = teleTitle[j].encode('UTF-8')
    entry = Label(content_frame,text=teleTitle[j].decode(),anchor='w', width=5, bd=2)
    entry.grid(row=0, column=j,padx=1, pady=1)

packet=1
for i in range(1,10):
    packetNum = Label(content_frame, text = packet, anchor="w",width=3)
    packetNum.grid(row=i, column=0,pady=0.5)
    packet = packet+1
    for j in range(1,25):
        takenData = Entry(content_frame,width=5)
        takenData.grid(row=i, column=j,pady=0.5)

# 鼠标滚轮滚动支持
def mouse_wheel_scroll(event):
    allTelemetryCanvas.yview_scroll(int(-1*(event.delta/120)), "units")
allTelemetryCanvas.bind_all("<MouseWheel>", mouse_wheel_scroll)

root.mainloop()

效果说明

修复后滚动条会固定在allTelemetry区域右侧,高度完全填满父容器,当内容高度超过Notebook设置的200px高度时,滚动条自动激活,可以拖动查看所有行的表格内容,同时支持鼠标滚轮快速滚动,内部表格宽度会自动适配Canvas宽度不会出现横向错位。

内容的提问来源于stack exchange,提问作者ayse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 07:24:15