更多部件

本章继续介绍几个小部件:列表框、滚动条、文本、缩放、微调按钮和进度条。其中一些比我们之前看到的基本功能更强大。在没有(或不需要)主题对应的情况下,我们还将在这里看到一些使用经典 Tk 小部件的实例。

列表框

列表框小部件显示一列单行文本项,允许用户浏览列表时选择一个或多个。

列表框是经典 Tk 小部件的一部分;主题 Tk 小部件集中目前没有列表框。

Tk 的 treeview 小部件(主题)也可以用作列表框(一层深的树),允许您在列表中使用图标和样式。无论是基于树视图还是可用扩展之一,多列(表)列表小部件也可能在某个时候将其纳入 Tk。

python tkinker列表 tkinter列表框_python tkinker列表


列表框小部件。

列表框是使用**Listbox**类创建。height配置选项可以指定列表框在不滚动的情况下一次显示的行数:

ls = Listbox(parent, height=10)

填充列表框项目

填充和管理列表框中的所有项目有一个简单的方法和一个困难的方法。

简单的方法。每个列表框都有一个listvariable配置选项,它允许您将一个变量(必须是一个列表)链接到列表框。这个列表的每个元素都是一个字符串,代表列表框中的一个项目。要在列表框中添加、删除或重新排列项目,您可以像修改任何其他列表一样简单地修改此变量。类似地,要找出例如哪个项目在列表框的第三行,只需查看列表变量的第三个元素。

其实没那么容易。Tkinter 不允许您将常规 Python 列表链接到listbox. 正如我们在 entry中看到的那样,我们需要使用 StringVar作为中介。它提供了 Python 列表和底层 Tk 小部件可以使用的字符串之间的映射。这也意味着无论何时我们更改列表,我们都需要更新StringVar.

choices = ["apple", "orange", "banana"]
choicesvar = StringVar(value=choices)
ls = Listbox(parent, listvariable=choicesvar)
...
choices.append("peach")
choicesvar.set(choices)

较旧的、更难的方法是使用一组属于列表框小部件本身的方法。它们对小部件维护的(内部)项目列表进行操作:
1. insert *idx* *item* *?item...?*``*idx*``end方法用于向列表中添加一项或多项;idx是一个从 0 开始的索引,指示应在其之前添加项目的项目的位置;指定将新项目放在列表的末尾。
2. delete *first* *?last?*``*first*``*last*``insert方法从列表中删除一项或多项;firstlast是根据insert方法的索引。
3. get *first* *?last?*``*first*``*last*方法返回给定位置的单个项目的内容,或和之间的项目列表。
4. size方法返回列表中的项目数。
之所以有困难,是因为该listvariable选项仅在 Tk 8.3 中引入。因为使用 list 变量可以让您使用所有标准列表操作,所以它提供了一个更简单的 API。如果您以较旧的方式操作列表框,值得考虑升级。

选择项目

您可以选择用户是否一次只能从listbox 中选择一个项目,或者是否可以同时选择多个项目。这由selectmode选项控制:默认情况下只能选择单个项目 ( browse),而 selectmodeextended时允许用户选择多个项目。

出于向后兼容性的原因,名称browseextended很糟糕。由于还有另外两种模式singlemultiple,您不应该使用它们(它们使用与现代用户界面和平台约定不一致的旧交互风格)。

要找出当前选择了列表框中的哪项或哪些项目,请使用curselection 方法。它返回当前选择的所有项目的索引列表;可能是一个空列表。对于选择模式browse 的列表,它永远不会超过一个项目。您还可以使用selection_includes *index*方法检查当前是否选择了具有给定索引的项目。

if lbox.selection_includes(2): ...

要以编程方式更改选择,您可以使用selection_clear *first* *?last?*方法取消选择单个项目或指定索引范围内的任何项目。要选择一个项目或一个范围内的所有项目,请使用selection_set *first* *?last?*方法。这两者都不会触及指定范围之外的任何项目的选择。

如果您更改选择,您还应该确保新选择的项目可见(即,它没有滚动到视图之外)。为此,请使用see *index*方法。

lbox.selection_set(idx)
lbox.see(idx)

当用户更改选择时,<<ListboxSelect>>会生成一个虚拟事件。您可以绑定到它以执行您需要的任何操作。根据您的应用程序,您可能还希望绑定到双击<Double-1>事件并使用它来调用当前选定项的操作。

lbox.bind("<<ListboxSelect>>", lambda e: updateDetails(lbox.curselection()))

样式化列表

像大多数“经典”Tk 小部件一样,您在修改列表框的外观方面具有极大的灵活性。如参考手册中所述,您可以修改列表框项的显示字体,正常状态下项目的前景色(文本)和背景色,选中时,禁用小部件时等。 还有一种 itemconfigure方法这允许您更改单个项目的前景色和背景色。

通常情况下,克制是有用的。通常,默认值将完全适合并且与平台约定很好地匹配。在我们马上要讨论的示例中,我们将展示如何限制使用这些选项可以产生良好的效果,在这种情况下,以稍微不同的颜色显示列表框的交替行。

保留额外的项目数据

listvariable(或内部列表,如果你使用老办法管理)保存在ListBox中给出的字符串。但是,通常情况下,您显示的每个字符串都与其他一些数据项相关联。这可能是一个对您的程序有意义的内部对象,但并不打算向用户显示。换句话说,您真正感兴趣的不是列表框中显示的字符串,而是关联的数据项。例如,一个列表框可能会向用户显示一个姓名列表,但您的程序真正感兴趣的是每个人的底层用户对象(或 ID 号),而不是特定的姓名。

我们如何将这个基础值与显示的名称相关联?不幸的是,列表框小部件本身不提供任何功能,因此我们必须单独管理它。有几种明显的方法。首先,如果保证显示的字符串是唯一的,您可以使用哈希表将每个名称映射到其关联的底层对象。这不适用于可能出现重复的人名,但可能适用于唯一的国家/地区。

第二种方法是保留第二个列表,与列表框中显示的字符串列表平行。第二个列表将保存与显示的每个项目相关联的基础对象。因此,显示的字符串列表中的第一项对应于基础对象列表中的第一项,第二项对应于第二项,依此类推。您在一个列表中所做的任何更改(插入、删除、重新排序),您必须在另一个列表中进行. 然后,您可以根据它们在列表中的位置,轻松地从显示的列表项映射到底层对象。

例子

这是一个愚蠢的例子,展示了这些列表框技术中的几种。我们将显示一个国家/地区列表。我们一次只能选择一个国家。当我们这样做时,状态栏将显示该国家/地区的人口。您可以按下一个按钮,将几件礼物中的一件送给所选国家的元首(好吧,不是真的,但请发挥您的想象力)。也可以通过双击列表或按回车键来触发发送礼物。

在幕后,我们并行维护两个列表。第一个是两个字母的国家/地区代码列表。另一个是我们将在列表框中显示的每个国家的相应名称。我们还有一个简单的哈希表,其中包含每个国家的人口,由两个字母的国家代码索引。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NlDVJaul-1628503013937)(https://tkdocs.com/images/country_w.png)]
国家选择器列表框示例。

from tkinter import *
from tkinter import ttk
root = Tk()

# Initialize our country "databases":
#  - the list of country codes (a subset anyway)
#  - parallel list of country names, same order as the country codes
#  - a hash table mapping country code to population
countrycodes = ('ar', 'au', 'be', 'br', 'ca', 'cn', 'dk', 'fi', 'fr', 'gr', 'in', 'it', 'jp', 'mx', 'nl', 'no', 'es', 'se', 'ch')
countrynames = ('Argentina', 'Australia', 'Belgium', 'Brazil', 'Canada', 'China', 'Denmark', \
        'Finland', 'France', 'Greece', 'India', 'Italy', 'Japan', 'Mexico', 'Netherlands', 'Norway', 'Spain', \
        'Sweden', 'Switzerland')
cnames = StringVar(value=countrynames)
populations = {'ar':41000000, 'au':21179211, 'be':10584534, 'br':185971537, \
        'ca':33148682, 'cn':1323128240, 'dk':5457415, 'fi':5302000, 'fr':64102140, 'gr':11147000, \
        'in':1131043000, 'it':59206382, 'jp':127718000, 'mx':106535000, 'nl':16402414, \
        'no':4738085, 'es':45116894, 'se':9174082, 'ch':7508700}

# Names of the gifts we can send
gifts = { 'card':'Greeting card', 'flowers':'Flowers', 'nastygram':'Nastygram'}

# State variables
gift = StringVar()
sentmsg = StringVar()
statusmsg = StringVar()

# Called when the selection in the listbox changes; figure out
# which country is currently selected, and then lookup its country
# code, and from that, its population.  Update the status message
# with the new population.  As well, clear the message about the
# gift being sent, so it doesn't stick around after we start doing
# other things.
def showPopulation(*args):
    idxs = lbox.curselection()
    if len(idxs)==1:
        idx = int(idxs[0])
        code = countrycodes[idx]
        name = countrynames[idx]
        popn = populations[code]
        statusmsg.set("The population of %s (%s) is %d" % (name, code, popn))
    sentmsg.set('')

# Called when the user double clicks an item in the listbox, presses
# the "Send Gift" button, or presses the Return key.  In case the selected
# item is scrolled out of view, make sure it is visible.
#
# Figure out which country is selected, which gift is selected with the 
# radiobuttons, "send the gift", and provide feedback that it was sent.
def sendGift(*args):
    idxs = lbox.curselection()
    if len(idxs)==1:
        idx = int(idxs[0])
        lbox.see(idx)
        name = countrynames[idx]
        # Gift sending left as an exercise to the reader
        sentmsg.set("Sent %s to leader of %s" % (gifts[gift.get()], name))

# Create and grid the outer content frame
c = ttk.Frame(root, padding=(5, 5, 12, 0))
c.grid(column=0, row=0, sticky=(N,W,E,S))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0,weight=1)

# Create the different widgets; note the variables that many
# of them are bound to, as well as the button callback.
# We're using the StringVar() 'cnames', constructed from 'countrynames'
lbox = Listbox(c, listvariable=cnames, height=5)
lbl = ttk.Label(c, text="Send to country's leader:")
g1 = ttk.Radiobutton(c, text=gifts['card'], variable=gift, value='card')
g2 = ttk.Radiobutton(c, text=gifts['flowers'], variable=gift, value='flowers')
g3 = ttk.Radiobutton(c, text=gifts['nastygram'], variable=gift, value='nastygram')
send = ttk.Button(c, text='Send Gift', command=sendGift, default='active')
sentlbl = ttk.Label(c, textvariable=sentmsg, anchor='center')
status = ttk.Label(c, textvariable=statusmsg, anchor=W)

# Grid all the widgets
lbox.grid(column=0, row=0, rowspan=6, sticky=(N,S,E,W))
lbl.grid(column=1, row=0, padx=10, pady=5)
g1.grid(column=1, row=1, sticky=W, padx=20)
g2.grid(column=1, row=2, sticky=W, padx=20)
g3.grid(column=1, row=3, sticky=W, padx=20)
send.grid(column=2, row=4, sticky=E)
sentlbl.grid(column=1, row=5, columnspan=2, sticky=N, pady=5, padx=5)
status.grid(column=0, row=6, columnspan=2, sticky=(W,E))
c.grid_columnconfigure(0, weight=1)
c.grid_rowconfigure(5, weight=1)

# Set event bindings for when the selection in the listbox changes,
# when the user double clicks the list, and when they hit the Return key
lbox.bind('<<ListboxSelect>>', showPopulation)
lbox.bind('<Double-1>', sendGift)
root.bind('<Return>', sendGift)

# Colorize alternating lines of the listbox
for i in range(0,len(countrynames),2):
    lbox.itemconfigure(i, background='#f0f0ff')

# Set the starting state of the interface, including selecting the
# default gift to send, and clearing the messages.  Select the first
# country in the list; because the <<ListboxSelect>> event is only
# fired when users makes a change, we explicitly call showPopulation.
gift.set('card')
sentmsg.set('')
statusmsg.set('')
lbox.selection_set(0)
showPopulation()

root.mainloop()

此示例中明显缺少的一件事是,虽然国家/地区列表可能很长,但一次只能显示其中的一部分。要在列表的更下方显示国家/地区,您必须用鼠标拖动或使用向下箭头键。滚动条会很好。让我们解决这个问题。

滚动条

一个滚动条小工具可以帮助用户看到另外一个小部件的全部内容,其内容通常比在可用的屏幕空间显示的内容多得多。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avDPlzE3-1628503013940)(https://tkdocs.com/images/w_scrollbar_all.png)]
滚动条小部件。

滚动条是使用**ttk.Scrollbar**类创建的:

s = ttk.Scrollbar( parent, orient=VERTICAL, command=listbox.yview)
listbox.configure(yscrollcommand=s.set)

与某些用户界面工具不同,Tk 滚动条不是另一个小部件(例如列表框)的一部分,而是完全独立的小部件。相反,滚动条与滚动小部件通过调用滚动控件的方法关联; 事实上,滚动的小部件还需要调用滚动条上的方法。

如果您使用的是最新的 Linux 发行版,您可能已经注意到,您在许多应用程序中看到的滚动条已更改为看起来更像您在 macOS 上看到的。Tk 中包含的任何默认主题都不支持 Linux 上的这种新外观。但是,一些第三方主题确实支持它。

orient配置选项确定是否在horizontalvertical方向滚动窗口小部件。然后您需要使用 command配置选项来指定如何与滚动小部件进行通信。这是在滚动条移动时调用滚动小部件的方法。

每个可以垂直滚动的小部件都包含一个名为 yview的方法,而那些可以水平滚动的小部件具有一个名为xview 的方法。只要存在此方法,滚动条就不需要了解有关滚动小部件的任何其他信息。当滚动条被操纵时,它会在方法调用中附加几个参数,指示它是如何滚动的,滚动到什么位置等。

滚动的小部件还需要与滚动条通信,告诉它现在整个内容区域的可见百分比。除了yview和/或xview方法之外,每个可滚动小部件还有一个yscrollcommandxscrollcommand 配置选项。这用于指定方法调用,它必须是滚动条的 set方法。同样,额外的参数将自动附加到方法调用上。

大多数滚动部件也有xscrollbaryscrollbar方法,将节省您写自己的麻烦commandxscrollcommand以及yscrollcommand需要回调来连接一个滚动部件的滚动条。相反,您只需执行以下操作:

如果出于某种原因,您想将滚动条从程序中移动到特定位置,您可以自己调用set *first* *last*方法。向它传递两个浮点值(介于 0 和 1 之间),指示可见内容区域的开始和结束百分比。

例子

列表框是几种可滚动的小部件之一。在这里,我们将构建一个非常简单的用户界面,由一个占据整个窗口的垂直可滚动列表框组成,底部只有一个状态行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6anzjFdu-1628503013948)(https://tkdocs.com/images/scrollbar_l.png)]
滚动列表框。

from tkinter import *
from tkinter import ttk

root = Tk()
l = Listbox(root, height=5)
l.grid(column=0, row=0, sticky=(N,W,E,S))
s = ttk.Scrollbar(root, orient=VERTICAL, command=l.yview)
s.grid(column=1, row=0, sticky=(N,S))
l['yscrollcommand'] = s.set
ttk.Label(root, text="Status message here", anchor=(W)).grid(column=0, columnspan=2, row=1, sticky=(W,E))
root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)
for i in range(1,101):
    l.insert('end', 'Line %d of 100' % i)
root.mainloop()

如果您看过本教程的早期版本,您可能还记得我们在此时引入了一个sizegrip小部件。它在窗口的右下方放置了一个小手柄,允许用户通过拖动手柄来调整窗口大小。这在某些平台上很常见,包括旧版本的 macOS。一些旧版本的 Tk 甚至会自动将此句柄添加到窗口中。

平台约定往往比长期存在的开源 GUI 工具包发展得更快。Mac OS X 10.7 取消了角落里的大小控制,支持从任何窗口边缘调整大小,最终赶上世界其他地方。除非迫切需要与 10 多年历史的操作系统在视觉上兼容,否则如果您的应用程序中有一个sizegrip ,最好将其删除。

文本

文本控件为用户提供了一个区域,使他们能够进入多行文本。文本小部件是经典 Tk 小部件的一部分,而不是主题 Tk 小部件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gl97ynj5-1628503013949)(https://tkdocs.com/images/w_text_all.png)]
文本小部件。

Tk 的文本小部件与画布小部件是两个超级强大的小部件之一,它们提供了非常深入但易于编程的功能。文本小部件已经形成了完整的文字处理器、大纲、Web 浏览器等的基础。我们将在后面的章节中介绍一些高级内容。在这里,我们将向您展示如何使用文本小部件来捕获相当简单的多行文本输入。

使用**Text**类创建文本小部件:

t = Text(parent, width=40, height=10)

widthheight,分别指定文本组件的请求的屏幕大小,字符和行。文本内容可以任意大。您可以使用wrap配置选项来控制如何处理换行:值是none(不换行,文本可以水平滚动)、char(在任何字符处换行)和word(换行只会发生在单词边界处)。

可以禁用文本小部件,以便无法进行编辑。因为文本不是主题小部件,所以通常stateinstate方法不可用。相反,请使用配置选项state,将其设置为disablednormal

txt['state'] = 'disabled'

滚动的工作方式与列表框相同。的xscrollcommandyscrollcommand 配置选项的文本组件附加到水平方向和/或垂直滚动条,并且xviewyview方法都是从滚动条调用。为了确保给定的行是可见的(即,不会滚动到视图之外),您可以使用该 see *index*方法,其中*index*的形式为*linenum.charnum*,例如, 5.0用于第 5 行(基于 1)的第一个(从 0 开始)字符。

内容

文本小部件没有与它们关联的链接变量,例如输入小部件。要检索整个文本小部件的内容,请调用方法get 1.0 end1.0 是一个文本的索引,意思是第一行的第一个字符,并且end是用于在最后一行的最后一个字符的索引的快捷方式。如果需要,可以提供其他索引来检索较小范围的文本。

可以使用insert *index* *string*方法将文本添加到小部件;*index*的使用格式是*line.char* 在表格中标记在其之前插入文本的字符;用于end 将文本添加到小部件的末尾。您可以使用 delete *start* *end*方法删除一系列文本,其中startend都是已经描述的文本索引。

我们将在后面的章节中介绍文本小部件的许多附加高级功能。

刻度

刻度小部件,用户可以选择直接操纵的数值。

python tkinker列表 tkinter列表框_列表框_02


缩放小部件。

使用以下**ttk.Scale**类创建刻度小部件:

s = ttk.Scale(parent, orient=HORIZONTAL, length=200, from_=1.0, to=100.0)

因为 ‘from’ 是 Python 中的保留关键字,所以我们在使用它作为配置选项时需要添加一个尾随下划线。

orient选项可以是horizontalvertical。该length 选项表示水平或垂直轴的长度,以屏幕单位(例如,像素)指定。您还应该定义刻度允许用户选择的数字范围;为此,请为每个fromto配置选项设置一个浮点数 。

有几种不同的方法可以设置刻度的当前值(它必须是fromto值之间的浮点值)。您可以设置(或读取,以获取当前值)秤的value配置选项。您可以使用该variable 选项将比例链接到变量。或者,您可以调用 scale 的方法来更改值,或 读取当前值的方法。set *value*``get

一个command配置选项可用于指定脚本调用每当规模改变。每次调用此脚本时,Tk 都会将比例的当前值作为参数附加(我们看到类似的事情,将额外的参数添加到滚动条回调中)。

# label tied to the same variable as the scale, so auto-updates
num = StringVar()
ttk.Label(root, textvariable=num).grid(column=0, row=0, sticky='we')

# label that we'll manually update via the scale's command callback
manual = ttk.Label(root)
manual.grid(column=0, row=1, sticky='we')

def update_lbl(val):
   manual['text'] = "Scale at " + val

scale = ttk.Scale(root, orient='horizontal', length=200, from_=1.0, to=100.0, variable=num, command=update_lbl)
scale.grid(column=0, row=2, sticky='we')
scale.set(20)

与其他主题的窗口小部件,您可以使用state disabledstate !disabledinstate disabled方法,以防止用户修改的规模。

由于比例小部件不显示实际值,您可能需要单独添加这些值,例如,使用标签小部件。

微调按钮

微调按钮插件允许用户选择号码(或实际上,从任意一个列表中的项目)。它通过将显示当前值的类似条目的小部件与一对小的向上/向下箭头相结合来实现这一点,这些小箭头可用于逐步浏览可能的选择范围。

主题微调按钮框是在 Tk 8.5.9(2010 年发布)中添加的。如果您必须运行旧版本,经典 Tk 小部件中有一个微调按钮框,尽管 API 略有不同。

python tkinker列表 tkinter列表框_上传_03


Spinbox 小部件。

Spinbox 小部件是使用以下**ttk.Spinbox**类创建的:

spinval = StringVar()
s = ttk.Spinbox(parent, from_=1.0, to=100.0, textvariable=spinval)

与缩放小部件一样,微调按钮框允许用户在特定范围(使用fromto配置选项指定)之间选择一个数字,尽管通过一个非常不同的用户界面。您还可以指定一个increment,它控制每次单击向上或向下按钮时值的变化程度。

与列表框或组合框一样,微调按钮框也可用于让用户从任意字符串列表中选择一个项目;这些可以使用values配置选项指定。这与组合框的工作方式相同;指定值列表将覆盖fromto设置。

在默认状态下,微调按钮框允许用户通过向上和向下按钮选择值,或者直接在显示当前值的输入区域中输入值。如果您想禁用后一个功能,以便只有向上和向下按钮可用,您可以设置readonly状态标志。

s.state(['readonly'])

与其他主题小部件一样,您也可以通过disabled状态标志禁用微调按钮框,或通过instate方法检查状态。Spinbox (微调按钮)还支持以与条目小部件相同的方式进行验证,使用validatevalidatecommand 配置选项。

您可能对何时选择比例、列表框、组合框、条目或微调按钮框感到困惑。通常,其中一些可用于相同类型的数据。答案实际上取决于您希望用户选择什么、平台用户界面约定以及该值在您的用户界面中扮演的角色。

例如,与列表框相比,组合框和微调按钮框占用的空间相当小。对于更外围的设置,它们可能更有意义。用户界面中更主要和突出的选择可能保证列表框占用的额外空间。当项目对它们没有自然和明显的排序时,Spinbox 没有多大意义。小心不要在组合框和微调按钮框中放置太多项目。这会使选择项目更加耗时。

有一个布尔wrap选项可确定当值超出起始值或结束值时是否应环绕。您还可以为width 保存微调按钮框当前值的条目指定一个。

同样有关于如何设置或获取 Spinbox 中的当前值的选择。通常,您会使用textvariable配置选项指定链接变量。像往常一样,对变量的任何更改都会反映在 spinbox 中,而 spinbox 中的任何更改都会反映在链接变量中。同样,和 方法允许您直接设置或获取值。set *value*``get

当用户按下向上 ( <<Increment>>) 或向下 ( <<Decrement>>)时,Spinbox 会生成虚拟事件。一个command配置选项允许你提供的任何改变调用的回调。

进度条

进度条控件提供反馈约冗长操作的进度用户。

在您可以估计完成操作需要多长时间的情况下,您可以显示已完成的部分。否则,您可以指示操作正在继续,但不建议需要多长时间。

python tkinker列表 tkinter列表框_列表框_04


进度条小部件。

使用**ttk.Progressbar**类创建进度条小部件:

p = ttk.Progressbar(parent, orient=HORIZONTAL, length=200, mode='determinate')

与缩放小部件一样,它们应该通过 配置选项被赋予一个方向(horizontalverticalorient,并且可以被赋予一个可选的length. 所述mode配置选项可以被设置为任一determinate,其中,所述进度将指示向完成,或以相对进展indeterminate,在那里它表明操作仍在继续,但是没有表现出相对进展。

确定进度

要使用确定模式,请估计完成操作所需的“步骤”总数。这可能是一段时间,但不是必须的。使用maximum配置选项将其提供给进度条。它应该是一个浮点数并默认为100.0(即,每一步为 1%)。

在您进行操作时,告诉进度条您使用value配置选项进行了多远。所以这将从 0 开始,然后向上计数到您设置的最大值。

这有两个细微的变化。首先,您可以将进度条的当前值存储在通过进度条的variable配置选项链接到它的变量中;这样,当您更改变量时,进度条将更新。另一种选择是调用进度条的方法。这会将值增加给定(默认为 1.0)。step *?amount?*``*amount*

不确定的进度

当您无法轻松估计您在长期运行的任务中实际完成了多远时,请使用不确定模式。但是,您仍然希望提供操作仍在继续(并且您的程序没有崩溃)的反馈。在操作开始时,您只需调用进度条的start方法。在操作结束时,调用其stop方法。进度条将负责其余的工作。

不幸的是,“进度条将处理其余部分”并不是那么简单。事实上,如果你start的进度条,调用一个需要几分钟才能完成的函数,然后stop进度条,你的程序会一直出现冻结,进度条不更新。事实上,它根本不会出现在屏幕上。哎呀!

要了解为什么会这样以及如何解决它,下一章将深入研究 Tk 的事件循环。