英文:
How to make progress bar work using PySimpleGUI in Python?
问题
我正在使用PySimpleGui的单行进度条来显示在我的主要函数运行时处理的文件。它大部分工作正常,但是当我将参数从1000更改为变量total_files
时,它只是闪烁,不停留在屏幕上。只有当参数保持为1000时,屏幕才会保持不变...但我想要显示真正处理的文件数量的进度。
例如,我有8个文件作为测试。我希望进度条保持在屏幕上,只显示这8个处理的文件。有人知道我做错了什么吗?
进度条的文档链接:
https://www.pysimplegui.org/en/latest/#progress-meters
for i in range(1,total_files):
sg.one_line_progress_meter('Loading...', i+1, 1000, 'key','Files Processed', orientation="horizontal")
以下是我的代码:
import PySimpleGUI as sg, pandas as pd, os, time
from pathlib import (
Path,
)
# 其他部分的代码...
如果您需要更多的帮助或有其他问题,请随时告诉我。
英文:
I am using PySimpleGui's one-line progress meter to show the files processed while my main function is running. It is working for the most part, however when I change the parameter from value of 1000 to my variable total_files it just flickers and never stays on screen. It's only when I keep the parameter to a value of 1000 does the screen stay put...but I want to just show the progress of the true amount of files processed.
For example, I have 8 files I am processing as a test. I want the progress bar to stay on the screen and just show those 8 files processed. Does anyone know what I'm doing wrong?
Documentation on progress meter:
https://www.pysimplegui.org/en/latest/#progress-meters
for i in range(1,total_files):
sg.one_line_progress_meter('Loading...', i+1, 1000, 'key','Files Processed', orientation="horizontal")
Below is my code:
import PySimpleGUI as sg, pandas as pd, os, time
from pathlib import (
Path,
)
def convert_to_csv(input_folder, output_folder, dataframe2, dataframe3):
start = time.time()
# Parentsupplierbrand mapping file. Change the filepath to where the file is stored on your computer.
df2 = pd.read_csv(rf"{dataframe2}", sep="|")
# KCS Section Codes mapping file. Change the filepath to where the file is stored on your computer.
df3 = pd.read_excel(rf"{dataframe3}")
# loop through only text files in the input folder and convert data
for files in os.listdir(input_folder):
if files.endswith(".txt"):
df1 = pd.read_csv(rf"{input_folder}/{files}", sep="\t", encoding="latin-1")
df1["BrandName"] = df1["Comp_Brand"].apply(
xlookup, args=(df2["BrandID"], df2["BrandName"])
)
# map columns to the desired headers
df1.rename(
columns={
"BrandName": "Competitor_Name",
"Comp_PN": "Competitor_PartNumber",
"CQ_Brand": "AAIA_Code",
"CQ_PN": "PartNumber",
},
inplace=True,
)
remove_columns = df1.loc[
:, ~df1.columns.isin(["Comp_Brand", "CQ_Desc", "PartID"])
]
new_columns = [
"Competitor_Name",
"Competitor_PartNumber",
"AAIA_Code",
"PartNumber",
]
table_output = remove_columns[new_columns]
# below code for constructing file name convention
kcs_section_codes = df3.values.tolist()
stringtwo = table_output.loc[0][2] # stringtwo is the AAIA_Code
for code in kcs_section_codes:
if code[0] == stringtwo:
# stringone is the matching value under BrandName in the KCS_Section_Codes file
# by looking up AAIA_Code from the initial file in the BrandCode column from the KCS_Section_Codes file
stringone = "".join(
e for e in code[1] if e.isalnum()
) # replace any character that is not a letter or number with an empty character.
filename = rf"{stringone}-{stringtwo}_Interchanges.txt"
outputfile = rf"{output_folder}/{filename}"
table_output.to_csv(
outputfile,
sep="\t",
index=False,
columns=[
"Competitor_Name",
"Competitor_PartNumber",
"AAIA_Code",
"PartNumber",
],
)
# progress bar
total_files = sum([len(files) for r, d, files in os.walk(output_folder)])
for i in range(1, total_files):
sg.one_line_progress_meter(
"Loading...",
i + 1,
1000,
"key",
"Files Processed",
orientation="horizontal",
)
# code below for returning stats of main function in a popup window
total_files = sum([len(files) for r, d, files in os.walk(output_folder)])
end = time.time()
result_time = end - start
time_formatted = time.strftime("%H:%M:%S", time.gmtime(result_time))
sg.popup_no_titlebar(
f"Done! :)\nTotal Files Processed: {total_files}\nExecution Time (hh:mm:ss): {time_formatted}"
)
def xlookup(lookup_value, lookup_array, return_array, if_not_found: str = ""):
match_value = return_array.loc[lookup_array == lookup_value]
if match_value.empty:
return f'"{lookup_value}" not found!' if if_not_found == "" else if_not_found
else:
return match_value.tolist()[0]
def is_valid_path(filepath):
if filepath and Path(filepath).exists():
return True
sg.popup_error("Filepath not correct")
return False
def gui():
sg.theme("DarkBlue3") # Add a touch of color
# All the stuff inside your window.
layout = [
[
sg.Text("Input Folder: "),
sg.Input(key="-IN-"),
sg.FolderBrowse(),
],
[sg.Text("Output Folder: "), sg.Input(key="-OUT-"), sg.FolderBrowse()],
[
sg.Text("Data Mapping File: Parent Supplier Brand"),
sg.Input(key="-DF2-"),
sg.FileBrowse(),
],
[
sg.Text("Data Mapping File: KCS Section Codes"),
sg.Input(key="-DF3-"),
sg.FileBrowse(),
],
[sg.Exit(), sg.Button("Convert to CSV")],
]
# Create the Window
window = sg.Window("Data Conversion", layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if (
event == sg.WIN_CLOSED or event == "Cancel"
): # if user closes window or clicks cancel
break
if event in (sg.WIN_CLOSED, "Exit"):
break
if (
event == "Convert to CSV"
): # if user clicks covert to csv button then call convert_to_csv function using inputs
if (is_valid_path(values["-IN-"])) and (is_valid_path(values["-OUT-"])):
convert_to_csv(
input_folder=values["-IN-"],
output_folder=values["-OUT-"],
dataframe2=values["-DF2-"],
dataframe3=values["-DF3-"],
)
window.close()
if __name__ == "__main__":
gui()
答案1
得分: 1
Following code update the progressbar without any time delay, so it will show in short time and reach the maximum value immediately, then the window for progressbar closed.
```python
for i in range(1, total_files):
sg.one_line_progress_meter(
"Loading...",
i + 1,
1000,
"key",
"Files Processed",
orientation="horizontal",
)
Reduce your code to ask question, it will help people to help.
Demo code:
from time import sleep
import PySimpleGUI as sg
from threading import Thread
def job(window):
window.write_event_value("Update", 0)
for i in range(1, 11):
sleep(0.2) # Simulate each step in the job
window.write_event_value("Update", i) # Cannot update GUI not in the main thread
window.write_event_value("Done", None)
sg.theme("DarkBlue3")
layout = [[sg.Button("Submit"), sg.Button("Exit")],]
window = sg.Window("Title", layout)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, "Exit"):
break
elif event == "Submit":
thread = Thread(target=job, args=(window, ), daemon=True)
thread.start()
elif event == "Update":
i = values[event]
sg.one_line_progress_meter("Loading...", i, 10, "key", "Files Processed", orientation="horizontal")
elif event == "Done":
print('Job done !')
window.close()
英文:
Following code update the progressbar without any time delay, so it will show in short time and reach the maximum value immediately, then the window for progressbar closed.
for i in range(1, total_files):
sg.one_line_progress_meter(
"Loading...",
i + 1,
1000,
"key",
"Files Processed",
orientation="horizontal",
)
Reduce your code to ask question, it will help people to help.
Demo code:
from time import sleep
import PySimpleGUI as sg
from threading import Thread
def job(window):
window.write_event_value("Update", 0)
for i in range(1, 11):
sleep(0.2) # Simulate each step in the job
window.write_event_value("Update", i) # Cannot update GUI not in the main thread
window.write_event_value("Done", None)
sg.theme("DarkBlue3")
layout = [[sg.Button("Submit"), sg.Button("Exit")],]
window = sg.Window("Title", layout)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, "Exit"):
break
elif event == "Submit":
thread = Thread(target=job, args=(window, ), daemon=True)
thread.start()
elif event == "Update":
i = values[event]
sg.one_line_progress_meter("Loading...", i, 10, "key", "Files Processed", orientation="horizontal")
elif event == "Done":
print('Job done !')
window.close()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论