python - 如何在 kivy-python 中使用带多线程的时钟对象更新进度条?

标签 python multithreading progress-bar kivy

我正在 kivy 中制作一个应用程序,因为我使用的是 linux。我在使用 python-kivy 中的多线程时钟对象更新进度条 gui 时遇到问题。我同时使用 .kv 和 .py 文件运行应用程序。

我的 main.py 文件:

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()

我的 .kv 文件:

<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

进度条是否完美更新?我想在实时更新它 prefectly。请告诉我执行此代码的更好方法。提前致谢。

最佳答案

您的代码有一些问题:

您的 UI 线程中有一个循环(这将停止 UI 更新)

        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

您需要像这样将循环传递到您的线程中:

   ...
   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!

还有更多的修复工作要做(风格方面),但这超出了上下文

注意 - 这没有经过任何测试......

关于python - 如何在 kivy-python 中使用带多线程的时钟对象更新进度条?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35111229/

相关文章:

python - group by 分组和平均

python - Keras 函数式 API 有什么特别之处?

multithreading - MonoTouch 6.x 中的线程模型更改?

c++ - Linux 上的互锁等效项

c# - 后台 worker 部分或全部更新 ProgressBar 然后炸弹爆炸

asp.net-mvc-4 - 如何在 MVC 4 中每 3 秒刷新一次局部 View ?

c# - 跨线程异常 - 使用 Invoke

python - 如何在 Windows 域服务器上发布离线 odoo 网站供公众查看

python - 没有名为 tensorflow.python.platform 的模块

swift - 线程 1 : EXC_BAD_INSTRUCTIONS | SWIFT