本人最近在用python的tkinter来生成界面,过程中遇到了不少问题,其中最让我难受的就是关于绑定Scrollbar的Text控件的问题。
问题的大概是这样的:
1. 首先我创建了一个Scrollbar控件,然后创建了一个Text控件用来保存每一行的内容。Text的yscrollcommand = scrollbar.set,scrollbar.config(command=text.yview)。网上的所有关于Scrollbar和Text之类的关联,都是用这种方式表示的,表明当Text里的内容超过行数限制时,Scrollbar会变成可上下拖动的;当向下拖动Scrollbar时,Text里有限行数显示的内容也会随之变化。
代码如下:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import tkinter
class FirstWindow(object):
def __init__(self):
self.top = tkinter.Tk()
self.scrollbar = tkinter.Scrollbar(self.top)
self.scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
self.text = tkinter.Text(self.top,
width=10,
height=10,
font=("Times New Roman", 16),
yscrollcommand=self.scrollbar.set)
self.text.pack()
self.scrollbar.config(command=self.text.yview)
self.button = tkinter.Button(text="点我",
command=self.click_me)
self.button.pack()
def click_me(self):
for i in range(20):
self.text.insert(tkinter.END, "这是第" + str(i) + "行\n")
def main():
FirstWindow()
tkinter.mainloop()
if __name__ == '__main__':
main()
我还添加了一个Button,来触发向Text里的每一行写入内容。
我在Text生成时,设定的高度为10,代表可以显示10行的内容,超过10行时,Scrollbar就可以滚动,来显示Text里显示不下的内容。
程序运行后显示的图片如下:
点击按钮"点我"后,显示的内容如下:
这时Text控件内只能显示前10行内容,后面十行的内容就需要通过向下拖动滚动条来显示:
这种实时的显示,就是需要通过两行代码来实现:
self.text = tkinter.Text(self.top,
width=10,
height=10,
font=("Times New Roman", 16),
yscrollcommand=self.scrollbar.set)
self.scrollbar.config(command=self.text.yview)
yscrollcommand=scrollbar.set 和scrollbar.config(command=text.yview)来实现。
重点来了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2. 很多时候,当我们点击了按钮"点我"后,希望Text控件内显示的内容是包含最后一行的内容,也就是说点击按钮后能产生如下图所示的情况:
这时,滚动条会自动拖到最下方来显示Text控件内最后一行的内容。也就是我们希望的能够实时刷新Text内容的现象。
这种方法的实现其实很简单,但是苦于几天来在网络上各种搜索都没有结果,于是本人认真浏览了__init__.py的文件,来搜寻实现这种需求的方法,终于在Yview类中找到了:
class YView:
"""Mix-in class for querying and changing the vertical position
of a widget's window."""
def yview(self, *args):
"""Query and change the vertical position of the view."""
res = self.tk.call(self._w, 'yview', *args)
if not args:
return self._getdoubles(res)
def yview_moveto(self, fraction):
"""Adjusts the view in the window so that FRACTION of the
total height of the canvas is off-screen to the top."""
self.tk.call(self._w, 'yview', 'moveto', fraction)
def yview_scroll(self, number, what):
"""Shift the y-view according to NUMBER which is measured in
"units" or "pages" (WHAT)."""
self.tk.call(self._w, 'yview', 'scroll', number, what)
就是yview_moveto()这个方法,传入的第一个参数self不用去管,所以对用户来说,只用传入一个fraction参数即可,这个fraction就表示调用此方法后,Text或者Lixtbox内显示的内容为总内容百分之多少的位置处,fraction的范围从0到1。
通过调用此方法,就可以实现每次向Text中插入超过行数限制的新内容时能够显示到最后一行内容处,程序修改如下:
def click_me(self):
for i in range(20):
self.text.insert(tkinter.END, "这是第" + str(i) + "行\n")
self.text.yview_moveto(1)
只需在click_me()方法中,循环插入所有内容后,调用yview_moveto(1),就可以让Text的内容显示至最后一行处。
有需要的朋友可以试试这个方法,希望能有所帮助!