tkinter-Scrollbar详解

本文介绍另一个控件Scrollbar,在tkinter-Text详解一文中有提到过Scrollbar,但是没有做过多的说明。因此本文将详解Scrollbar及其使用场景。

Scrollbar

Scrollbar 一般和其他控件联合使用,当被显示的控件的内容大于可显示区域时,使用Scrollbar可显示更多的内容。一般垂直滚动条(vertical scrollbar)和Listbox, Text and Canvas联合使用;水平滚动条(horizontal scrollbar)也可作用于Entry。

首先还是介绍Scrollbar的常用属性和方法,最后再举几个结合其他控件的实例。

element

scrollbar的5个elements
在这里插入图片描述

arrow1,arrow2 指滚动条两端的箭头

slider 指scrollbar中的滑块

trough1,trough2 指非slider区域,可以称为

可通过slider拖动来改变视图,也可点击 arrow1或arrow2来改变视图,也可点击 trough1或trough2来改变视图。所谓视图,简单讲就是滑块的位置发生了改变,相应的显示内容也跟着变化。

orient

滚动条方向属性,通常有两个值"vertical"(默认值)和"horizontal"。即垂直滚动条和水平滚动条。

# bar = Scrollbar(main_win, orient=VERTICAL)
bar = Scrollbar(main_win, orient=HORIZONTAL)
bar.pack()

activebackground

当鼠标在滑块(slider)或箭头(arrowhead)上时,显示的背景颜色。windows上实测无效。

bar = Scrollbar(main_win, activebackground='red')
bar.pack()

background

指定背景颜色。window上实测无效

bar = Scrollbar(main_win, background='red')
bar.pack()

cursor

指定光标样式

bar = Scrollbar(main_win, cursor='cross')
bar.pack()

jump

控制用户拖动滑块时发生的动作。默认(jump=0)每拖动一次滑块,就会使command指定的回调函数被调用。如果jump=1,回调函数只在用户放开鼠标按键时被调用一次,在拖动过程中不会被触发。windows上实测无效。

repeatdelay

延迟x秒移动滑块。鼠标左键按下x秒数后,滑块在某个方向开始持续移动。通常用于滚动条中的向上和向下的箭头。windows上实测无效。

repeatinterval

一旦滑块在某方向的持续移动开始,repeatinterval决定了相邻两次移动动作的时间间隔, 一般和repeatdelay联合使用。windows上实测无效。

takefocus

可以使用tab键将焦点切换到scrollbar。如果takefocus=0,那么将关闭该功能。

command

对于scrollbar非常重要的交互属性。通常用于指定可滚动控件(scrollable widget)的xview或yview函数。

因为滚动条有两种动作: ‘moveto’和’scroll’,'moveto’对应slider的拖动,'scroll’对应arrow或trough的点击。我们来看看怎样指定command对应的回调函数。

from tkinter import (Tk, Text, Scrollbar)
from tkinter.constants import (HORIZONTAL, VERTICAL, RIGHT, LEFT, X, Y, BOTH, BOTTOM, YES)

def cb():
   print('first cb')

main_win = Tk()
main_win.title('渔道的Scrollbar控件')
main_win.geometry(f'{800}x{800}')

# create Scrollbar
scrollbar_v = Scrollbar(main_win)
scrollbar_v.pack(side=RIGHT, fill=Y)
scrollbar_h = Scrollbar(main_win, orient=HORIZONTAL)
scrollbar_h.pack(side=BOTTOM, fill=X)
text = Text(main_win, width=40, height=40)
text.config(yscrollcommand=scrollbar_v.set)
text.pack(expand=YES,fill=BOTH)
for i in range(1, 1000):
    text.insert(f'{i}.0', f'line:{str(i)}\n')
    
scrollbar_v.config(command=cb)

main_win.mainloop()

运行上面的代码会出现如下界面:

在这里插入图片描述

当我拖动slider时,报错TypeError: cb() takes 0 positional arguments but 2 were given

当我点击arrow或trough时,报错TypeError: cb() takes 0 positional arguments but 3 were given

说明scrollbar内部在调用回调函数cb()时,会给它传递参数。拖动slider时,传递了两个参数;点击arrow或trough时,传递了三个参数。显然,要想使用一个回调函数来处理这两种事件,那么就需要给回调函数指定可变参数(即可传入2个参数也可传入3个参数),我们知道python的函数时支持这种语法的,实现起来非常容易。

可以将cb()改成如下代码:

def cb(*args):
    argc = len(args)
    if argc == 2:
        print(f'{args[0]}, {args[1]},drag slider...')
    elif argc == 3:
        print(f'{args[0]}, {args[1]}, {args[2]},hit arrow...')
    else:
        print('invalid parameters number')

再次运行修改后的程序,

拖动slider,可以看到如下打印信息moveto, 0.0235,drag slider...

点击arrow或trough,可以看到如下打印信息scroll, 1, units,hit arrow...

通过上述实践过程,可以得到如下结论:

  1. 拖动slider(对应’moveto’事件)时,触发command指定的回调函数,该回调函数有2个参数cb1(action, fraction)
  2. 点击arrow或trough(对应’scroll’事件)时,触发command指定的回调函数,该回调函数有3个参数cb2(action,number,pages)
  3. 可以通过可变参数将回调函数接口统一

已知scrollbar.config(command=text.yview)支持对slider、arrow、trough的响应,为什么呢?原因就在于类XView,YView
为了接口统一,在tkinter中 创建了类XView,YView, 在YView中,定义了函数yview(*args),这样text就可以支持’moveto’和’scroll’。与我们前面定义的cb(*args)本质上是一样的。

set()

set(first, last)

设置scrollbar的slider的位置,通常作为可滚动控件的回调函数。first和last的值的范围是[0,1]的小数,first到last的区间指定了与scrollbar绑定的可滚动控件的可视内容的范围。

tkinter-Text详解一文的给Text加上滚动条一节的实例中,细心的同学可能发现了这样一个问题:无论是拖动slider还是点击arrow1、arrow2还是点击trough1、trough2,视图都没有发生变化;但是将鼠标放在Text区域,上下滚动鼠标滚轮,发现视图发生变化而且slider也跟着变化。接下来,会细品该问题背后的原因。

什么是可滚动控件?

class Text(Widget, XView, YView)
class Listbox(Widget, XView, YView)
class Entry(Widget, XView)
class Canvas(Widget, XView, YView)
class Spinbox(Widget, XView)

Text,Listbox,Entry,Canvas,Spinbox都是可滚动控件。也就是说继承于XView和(或)YView的控件类都是可滚动控件。

scrollbar和可滚动控件的关系?

scrollbar控件不是作为其他可滚动控件的一部分,两者之间只是组合关系,而不是包含关系。

scrollbar与可滚动控件的绑定

scrollbar和可滚动控件 之间的绑定是相互的,scrollbar既要主动绑定可滚动控件的相关函数,可滚动控件也要主动绑定scrollbar的相关函数。
例如,scrollbar.config(command=text.yview),text.config(yscrollcommand=scrollbar.set)
如果只绑定了scrollbar.config(command=text.yview),那么只有对滚动条进行操作(drag slider,点击arrow,trough)时,text的视图才会随着变动;而对text进行操作(滚动鼠标滚轮)时,滚动条视图(slider)不会跟着变化
如果只绑定了text.config(yscrollcommand=scrollbar.set),那么只有对text进行操作(滚动鼠标滚轮)时,滚动条视图才会跟着变化;而对滚动条(scrollbar)进行操作(drag slider,点击arrow,trough)时,text的视图不会随着变动
所以,只有对 scrollbar和可滚动控件 相互绑定,才能实现操作任一种控件,两者视图都会同步变化.

from tkinter import (Tk, Text, Scrollbar)
from tkinter.constants import (HORIZONTAL, VERTICAL, RIGHT, LEFT, X, Y, BOTH, BOTTOM, YES)

main_win = Tk()
main_win.title('渔道的Scrollbar控件')
main_win.geometry(f'{800}x{800}')

scrollbar_v = Scrollbar(main_win)
scrollbar_v.pack(side=RIGHT, fill=Y)
scrollbar_h = Scrollbar(main_win, orient=HORIZONTAL)
scrollbar_h.pack(side=BOTTOM, fill=X)
text = Text(main_win, width=40, height=40)
text.config(yscrollcommand=scrollbar_v.set) # text绑定垂直滚动条
text.config(xscrollcommand=scrollbar_h.set) # text绑定水平滚动条
text.pack(expand=YES,fill=BOTH)
for i in range(1, 1000):
    text.insert(f'{i}.0', f'line:{str(i)}\n')
    
scrollbar_v.config(command=text.yview) # 垂直滚动条绑定text
scrollbar_h.config(command=text.xview) # 水平滚动条绑定text

main_win.mainloop()

读者可以执行上述代码来 体验实际的效果。无法用语言描述。

  • 18
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sif_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值