问题
I am making an app in kivy for that i am using linux. i am getting a problem to update the progress bar gui using clock object with multithreading in python-kivy. i am using both files .kv & .py file run the app.
my main.py file:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.progressbar import ProgressBar
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.clock import Clock
import sys, threading, os, time
from socket import *
class Out_Come(BoxLayout):
def Input_manager(self, *args):
try:
t = self.ids.nd.text
I=socket.gethostbyname(t)
st = self.ids.ti.text
et = self.ids.it.text
st1=int(st)
et1=int(et)
while st1<=et1:
work=my_function(I,st1)
work.start()
Clock.schedule_once(lambda dt: work.run, 1)
st1=st1+1
self.ids.pb.value=self.ids.pb.value+1
except:
"Error"
class my_function(threading.Thread):
def __init__(self,n, d):
threading.Thread.__init__(self)
self.n = n
self.d = d
def run(self):
try:
get = socket(AF_INET, SOCK_STREAM)
get.settimeout(4)
get.connect((gethostbyname(self.n), int(self.d)))
print"done", self.d
get.close()
except:
print"not done", self.d
class Example_app(App):
def build(self):
return Out_Come()
if __name__ == '__main__':
Example_app().run()
my .kv file:
<Out_Come>:
GridLayout:
orientation:'vertical'
rows:2
cols:2
padding:10
spacing:10
Label:
text:"[b]Enter value:[b]"
markup:True
size_hint:.3,.3
TextInput:
id:nd
text: ""
height:40
multiline:False
GridLayout:
orientation: 'vertical'
rows:2
cols:4
padding:10
spacing:10
Label:
text:"[b]First:[b]"
height:40
size_hint:.25,.25
markup:True
TextInput:
id:ti
text:""
height: 40
size_hint:.25,.25
multiline:False
Label:
text:"[b]last[b]"
height:40
size_hint:.25,.25
markup:True
TextInput:
id:it
text:""
height:40
size_hint:.25,.25
multiline:False
GridLayout:
orientation: 'vertical'
rows:1
cols:2
padding:10
spacing:10
Button:
id:get
text:'Start'
size_hint:.3,.3
on_press: root.Input_manager()
ProgressBar:
id:pb
max:100
value:0
Is the progress bar perfectly updating? i want upate it prefectly in live time. Please tell me the better way to execute this code. Thanks in advance.
回答1:
Your code is has a few problems:
You have a loop in your UI thread (which will stop the UI updating)
while st1<=et1:
work=my_function(I,st1)
work.start()
Clock.schedule_once(lambda dt: work.run, 1)
st1=st1+1
self.ids.pb.value=self.ids.pb.value+1
You need to pass the loop into your thread like this:
...
def Input_manager(self, *args):
...
st1=int(st)
et1=int(et)
work=my_function(I,st1, est1,
#sending a thread safe update progress bar function
lambda : Clock.schedule_once(self.update_bar))
work.start()
def update_bar(self, dt=None):
self.ids.pb.value=self.ids.pb.value+1
class my_function(threading.Thread):
def __init__(self,n, st, et, update_bar):
threading.Thread.__init__(self)
self.n = n
self.st = st
self.et = et
self.update_bar = update_bar
def run(self):
for din range(self.st1, self.et1+1):
try:
get = socket(AF_INET, SOCK_STREAM)
get.settimeout(4)
get.connect((gethostbyname(self.n), int(d)))
print"done", d
get.close()
except:
print"not done", d
finally:
self.update_bar() #this is our callback to update the bar!
There are more fixes to be done (style wise) but that is outside the context
Note - this was not tested by any means...
来源:https://stackoverflow.com/questions/35111229/how-to-update-progressbar-using-clock-object-with-multithreading-in-kivy-python