我正在尝试编写一个简单的应用程序,它将生成带有一些图表的 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
。
使用
Clock.schedule_once()
不会在另一个线程中执行代码。它实际上在主线程上运行它。您可以使用 threading
在另一个线程上执行代码,然后在 @mainthread
方法上添加 update_progress()
装饰器以强制其在主线程上运行。