我看到有人迷惑该如何创建一个进度度并更新它。所以我决定做了一不例从一个Thread中更新进度条。这篇批导中,我会创建一个有一个按钮的面版。但按钮被点击后,就会加载一个拥有进度条的对话框并启动一个线程。这是个虚拟线程,除了在20秒内每秒反馈一次更新以外什么都不做,然后这个对话框就销毁了。让我们去试试:
-
import
time
-
import wx
-
-
from
threading
import Thread
-
-
from wx.
lib.
pubsub
import Publisher
-
-
########################################################################
-
class TestThread
(Thread
):
-
"""Test Worker Thread Class."""
-
-
#----------------------------------------------------------------------
-
def
__init__
(
self
):
-
"""Init Worker Thread Class."""
-
Thread.
__init__
(
self
)
-
self.
start
(
)
# start the thread
-
-
#----------------------------------------------------------------------
-
def run
(
self
):
-
"""Run Worker Thread."""
-
# This is the code executing in the new thread.
-
for i
in
range
(
20
):
-
time.
sleep
(
1
)
-
wx.
CallAfter
(Publisher
(
).
sendMessage
,
"update"
,
""
)
-
-
########################################################################
-
class MyProgressDialog
(wx.
Dialog
):
-
""""""
-
-
#----------------------------------------------------------------------
-
def
__init__
(
self
):
-
"""Constructor"""
-
wx.
Dialog.
__init__
(
self
,
None
, title
=
"Progress"
)
-
self.
count
=
0
-
-
self.
progress
= wx.
Gauge
(
self
,
range
=
20
)
-
-
sizer
= wx.
BoxSizer
(wx.
VERTICAL
)
-
sizer.
Add
(
self.
progress
,
0
, wx.
EXPAND
)
-
self.
SetSizer
(sizer
)
-
-
# create a pubsub listener
-
Publisher
(
).
subscribe
(
self.
updateProgress
,
"update"
)
-
-
#----------------------------------------------------------------------
-
def updateProgress
(
self
, msg
):
-
"""
-
Update the progress bar
-
"""
-
self.
count +
=
1
-
-
if
self.
count
>=
20:
-
self.
Destroy
(
)
-
-
self.
progress.
SetValue
(
self.
count
)
-
-
-
########################################################################
-
class MyFrame
(wx.
Frame
):
-
-
#----------------------------------------------------------------------
-
def
__init__
(
self
):
-
wx.
Frame.
__init__
(
self
,
None
, title
=
"Progress Bar Tutorial"
)
-
-
# Add a panel so it looks the correct on all platforms
-
panel
= wx.
Panel
(
self
, wx.
ID_ANY
)
-
self.
btn
= btn
= wx.
Button
(panel
, label
=
"Start Thread"
)
-
btn.
Bind
(wx.
EVT_BUTTON
,
self.
onButton
)
-
-
sizer
= wx.
BoxSizer
(wx.
VERTICAL
)
-
sizer.
Add
(btn
,
0
, wx.
ALL|wx.
CENTER
,
5
)
-
panel.
SetSizer
(sizer
)
-
-
#----------------------------------------------------------------------
-
def onButton
(
self
, event
):
-
"""
-
Runs the thread
-
"""
-
btn
= event.
GetEventObject
(
)
-
btn.
Disable
(
)
-
-
TestThread
(
)
-
dlg
= MyProgressDialog
(
)
-
dlg.
ShowModal
(
)
-
-
btn.
Enable
(
)
-
-
#----------------------------------------------------------------------
-
# Run the program
-
if __name__
==
"__main__":
-
app
= wx.
App
(
False
)
-
frame
= MyFrame
(
)
-
frame.
Show
(
)
-
app.
MainLoop
(
)
MyFrame
类,一旦你运行脚本你会看到这个:
![](http://static.s.xdarui.com/images/progressBarFrame-300x187.png)
正如你所见,这见代码只是创建了个有一个按钮的面版。如果你按下按钮你会看到建议了下面的对话框并启动了一新的线程:
![](http://static.s.xdarui.com/images/progressBarDlg-300x190.png)
让我们来看看创建对话框部分的代码:
-
########################################################################
-
class MyProgressDialog
(wx.
Dialog
):
-
""""""
-
-
#----------------------------------------------------------------------
-
def
__init__
(
self
):
-
"""Constructor"""
-
wx.
Dialog.
__init__
(
self
,
None
, title
=
"Progress"
)
-
self.
count
=
0
-
-
self.
progress
= wx.
Gauge
(
self
,
range
=
20
)
-
-
sizer
= wx.
BoxSizer
(wx.
VERTICAL
)
-
sizer.
Add
(
self.
progress
,
0
, wx.
EXPAND
)
-
self.
SetSizer
(sizer
)
-
-
# create a pubsub listener
-
Publisher
(
).
subscribe
(
self.
updateProgress
,
"update"
)
-
-
#----------------------------------------------------------------------
-
def updateProgress
(
self
, msg
):
-
"""
-
Update the progress bar
-
"""
-
self.
count +
=
1
-
-
if
self.
count
>=
20:
-
self.
Destroy
(
)
-
-
self.
progress.
SetValue
(
self.
count
)
wx.Gauge
部件创建一个对话框。这个
Gauge
只是进度条背后的实际部件。然后,我们在对话框的
__init__
末尾加入了发布器的监听,这监听会接受来自
updateProgress
方法中触发事件的消息。我们会在线程中看到这个消息。在更新进度条方法中,我们增加计数并通过设置
wx.Gauge
的值去更新它。我们同样要检查计数器是不是小于20,如果达到了就销毁这个对话框。
现在我们来看线程中的代码:
-
########################################################################
-
class TestThread
(Thread
):
-
"""Test Worker Thread Class."""
-
-
#----------------------------------------------------------------------
-
def
__init__
(
self
):
-
"""Init Worker Thread Class."""
-
Thread.
__init__
(
self
)
-
self.
start
(
)
# start the thread
-
-
#----------------------------------------------------------------------
-
def run
(
self
):
-
"""Run Worker Thread."""
-
# This is the code executing in the new thread.
-
for i
in
range
(
20
):
-
time.
sleep
(
1
)
-
wx.
CallAfter
(Publisher
(
).
sendMessage
,
"update"
,
""
)
time
模块在每次的循环暂停一秒。在每次的暂停之后,它都会发一个消息以告诉对话框更新进度条。
总结
这里你要知道在一个线程中如何创建你自己的进度条对话框。你可以修改这段代码,并用之创建一个文件下载器。如果你真的这样做了,你就得检查下载文件的大小和下载块,所以你可以在适当的范围内创建wx.Gauge
并在下载过程中更新它。我希望这可以对你的项目会有些帮助。