更新kivy.uix.progressbar.ProgressBar时出现问题

问题描述 投票:0回答:1

我正在尝试编写一个简单的应用程序,它将生成带有一些图表的 pdf 报告。我还想添加一个

progressbar window
,您可以在其中看到程序的进度。好吧,我做到了,但是我的小部件有问题。也就是说,执行任务时,进度条
value
会增加,但您看到的小部件却没有

这是为什么呢?我不知道。这就是为什么我向你寻求帮助。

我的代码

图书馆

import os
import re
import time
from fpdf import FPDF
from matplotlib import pyplot as plt
import pandas as pd

# set window size
from kivy.config import Config
Config.set('graphics', 'width', '450')
Config.set('graphics', 'height', '300')

import kivy
from kivy.app import App
from kivy.uix.progressbar import ProgressBar
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.filechooser import FileChooserListView
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.clock import Clock

GeneratePDF 类的主体

class FileChooserPopup(Popup):
    pass        

class GeneratePDF():
    def __init__(self, app_instance, **kwargs):
        super().__init__(**kwargs)
        self.app_instance = app_instance


    # --- other methods ---

    def create_progress_popup(self):
        # show progress popup
        content = BoxLayout(orientation='vertical')
        self.progress_bar = ProgressBar(max=100, value=0, size_hint_x=0.8,
                                        pos_hint={'center_x':0.5, 'center_y':0.5})
        self.percent_label = Label(text='0%', size_hint=(None, None),
                                size = (40,30),
                                pos_hint ={'center_x': 0.5,'center_y': 0.5})
        content.add_widget(self.progress_bar)
        content.add_widget(self.percent_label)
        self.progress = Popup(title='', content=content, size_hint=(0.8,0.8),
                              separator_height=0)
       
        # dismiss the file chooser popup
        self.app_instance.file_chooser.dismiss()

        self.progress.open()

    def update_progress(self, value):
        current = self.progress_bar.value
        current += value
        self.progress_bar.value = current
        self.percent_label.text = f'{int(current)}%'

    # --- other methods ---

    def generate_raport1(self, instance, selection, *args):
        # opening file
        if selection:
            self.selected_file = selection[0]

            # Create the progress popup
            self.create_progress_popup()

            # start generating raport inthread
            Clock.schedule_once(lambda dt: self.generate_report2(), 0)
        else:
            # dismiss the file chooser popup
            self.app_instance.file_chooser.dismiss()

    def generate_report2(self):
       
        # drawing plots and updating progressbar
        self.plot1(self.selected_file)
        self.update_progress(20)

        self.plot2()
        self.update_progress(20)

        self.plot3()
        self.update_progress(20)

        self.plot4()
        self.update_progress(20)

        # generate pdf raport
        self.write_pdf()
        self.update_progress(20)
        time.sleep(1)

        # deleting unnecessary png files
        for plot in self.plots: os.remove(plot)
       
        # showing message
        self.show_message_box()    

应用程序主体

class RaportApp(App):
   
    def build(self):
        self.layout = RelativeLayout()
        self.generate_pdf = GeneratePDF(app_instance=self)
        self.button = Button(text="Choose File", on_release=self.show_file_chooser,
                             size_hint=(None,None), size=(200,50),
                             pos_hint={'center_x':0.5,'center_y':0.5})
        self.layout.add_widget(self.button)
        return self.layout
   
    def show_file_chooser(self, *args):
        username = os.getenv("USERNAME")
        content = FileChooserListView(path = f'C:\\Users\\{username}\\Desktop', filters=['*.csv'])
        self.file_chooser = FileChooserPopup(title="Choose a *.csv file", content=content, size_hint=(0.8, 0.8))
        content.bind(on_submit=self.generate_pdf.generate_raport1)
        self.file_chooser.open()

    def update_progress(self, value):
        self.generate_pdf.update_progress(value)

if __name__ == '__main__':
    RaportApp().run()

这是我的应用程序的最后一个版本。我正在使用

Python 3.10
kivy 2.2.1

python kivy progress-bar python-3.10
1个回答
0
投票

使用

Clock.schedule_once()
不会在另一个线程中执行代码。它实际上在主线程上运行它。您可以使用
threading
在另一个线程上执行代码,然后在
@mainthread
方法上添加
update_progress()
装饰器以强制其在主线程上运行。

© www.soinside.com 2019 - 2024. All rights reserved.