滚动条也是常用控件的一种,它的动作和Scale控件有些类似,主要的区别是可以用滑块宽度(或高度)表现当前显示区域和整个区域的比例关系。Scrollbar的基本动作视频如下:


首先构建一个用于显示信息的标签控件:

 

label = Label(root, width = 50)label.grid(row=0, column=0, columnspan=2)


 


接下来构建第一个Scrollbar控件。如果不做任何处理的话,用户虽然可以拖动滑块,但一旦释放鼠标,滑块就会回到原来位置。为了解决这个问题,代码中实现了一个on_scroll函数。


 


 

def on_scroll(*args):    pos = scroll_bar.get()    print(pos)    page = 0.1    if args[0]=='scroll':        if args[2]=='units':            first =  pos[0] + int(args[1])* 0.01        elif args[2]=='pages':            first =  pos[0]  + int(args[1])* 0.1        else:            first = 0    elif args[0]=='moveto':        first = float(args[1])    else:        first = 0    scroll_bar.set(first,first + 0.1)    label.config(text=str(args))
scroll_bar = Scrollbar(root, orient = HORIZONTAL, command=on_scroll)scroll_bar.grid(row = 1, column=0, columnspan=2, sticky=W+E)

函数首先判断on_scroll的参数,如果一个参数是'scroll',则意味着本次通次是用户的滚动操作,而滚动又分为两种:一种是鼠标点击两端小三角时产生的以'unit'为单位的滚动,另一种是鼠标点击滑块以外的空白区域时产生的以'page'为单位的滚动。中间的参数可以是1或者-1,用于表明滚动的方向。

如果用户直接拖动滑块,则会产生一个'moveto'事件,它的参数是滑块的位置。

on_scroll对事件信息进行适当的处理之后调用Scrollbar的set方法分别指定滑块的开始位置和结束位置才能实现滑块按照操作移动的功能。需要说明的是:Scrollbar并没有提供指定滚动范围的功能,这个范围固定为[0,1]。

这种方式虽然可以使用Scrollbar实现滚动功能,但是每次都要自己编写处理相应滚动事件的代码,过程比较繁琐。于是我们在本连载中第一次引入类的概念,对滚动条功能进行简单的封装之后,提供一个ScrollbarEx类:


 


 

class ScrollbarEx(Scrollbar):    def __init__(self, master, **args):        arg_dict = copy.copy(args)        try:            self.min = arg_dict.pop('min')        except KeyError:            self.min = 0        try:            self.max = arg_dict.pop('max')        except KeyError:            self.max = 1        try:            self.page = arg_dict.pop('page')        except KeyError:            self.page = 0.1        try:            self.unit = arg_dict.pop('unit')        except KeyError:            self.unit = 0.01        try:            self.on_scroll = arg_dict.pop('on_scroll')        except KeyError:            pass        arg_dict.update(command = self.scroll_handler)        Scrollbar.__init__(self, master, arg_dict, )        self.scroll_handler()
def scroll_handler(self, *args): pos = self.get() span = self.max - self.min page = self.page / span unit = self.unit / span first = 0 if args: if args[0]=='scroll': if args[2]=='units': first = pos[0] + int(args[1])* unit elif args[2]=='pages': first = pos[0] + int(args[1])* page else: first = 0 elif args[0]=='moveto': first = float(args[1]) else: first = 0 self.set(first, first + page) if self.on_scroll: self.on_scroll(int(self.min + first * span), int(self.min + first * span + self.page))

ScrollBarEx所做的事情和前面说明的滚动事件处理没有什么不同,目的只是在于简化用户的使用过程。有了这个类,用户可以可Scrollbar同样的感觉使用滚动条功能:

 

def on_scroll_ex(first, last):    label.config(text="first={},last={}".format(first, last))
scrollbar_ex = ScrollbarEx(root, min=0, max=100, page=10, unit=2, on_scroll=on_scroll_ex, orient = HORIZONTAL)scrollbar_ex.grid(row=2, column=0, columnspan=2, sticky=W+E)

用户要做的只是通过min,max,page,unit几个单数指定滚动的范围,页滚动距离,单位滚动距离等信息而不用关心事件处理的细节。

 

完整代码可以从下面的链接下载:

​https://github.com/xueweiguo/TkinterPrimer/blob/master/Sample/16%20Scrollbar.py​

 

觉得本文有帮助?请分享给更多人。

阅读更多更新文章,请扫描下面二维码,关注微信公众号【面向对象思考】