Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 96 #97

Merged
merged 3 commits into from
Nov 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions sinner/gui/controls/ProgressBarManager.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,74 @@
# a progressbar with display label
from threading import Lock
from tkinter import Misc, Label, StringVar, HORIZONTAL, BOTH, RIGHT, LEFT, NW
from tkinter.ttk import Progressbar
from typing import Dict


class ProgressBar:
_title: str
_parent: Misc | None
_parent: Misc
_pb: Progressbar
_label: Label
_progressVar: StringVar

def __init__(self, parent: Misc | None, max_value: float, initial_value: float, title: str = "Progress"):
_exists: bool = False

def __init__(self, parent: Misc, max_value: float, initial_value: float, title: str = "Progress"):
self._title = title
self._parent = parent
self._pb = Progressbar(self._parent, orient=HORIZONTAL, mode="determinate", maximum=max_value, value=initial_value)
self._progressVar = StringVar(value=self.progress_text)
self._label = Label(self._parent, textvariable=self._progressVar)
self._pb.pack(side=LEFT, expand=True, fill=BOTH)
self._label.pack(anchor=NW, side=RIGHT, expand=False, fill=BOTH, after=self._pb)
self._exists = True

@property
def value(self) -> float:
return float(self._pb.cget('value'))
if self._exists:
return float(self._pb.cget('value'))
return 0

@value.setter
def value(self, value: float) -> None:
self._pb.configure(value=value)
if self._exists:
self._pb.configure(value=value)

@property
def maximum(self) -> float:
return float(self._pb.cget('maximum'))
if self._exists:
return float(self._pb.cget('maximum'))
return 0

@maximum.setter
def maximum(self, value: float) -> None:
self._pb.configure(maximum=value)
if self._exists:
self._pb.configure(maximum=value)

@property
def progress_text(self) -> str:
return f"{self._title}: {int(self.value)}/{int(self.maximum)}"

def destroy(self) -> None:
self._exists = False
self._pb.destroy()
self._label.destroy()
if self._parent:
self._parent.update()

def update(self) -> None:
self._progressVar.set(self.progress_text)
self._pb.update()
if self._exists:
self._progressVar.set(self.progress_text)
self._pb.update()


# there are many progressbars can be shown at the same time, so class tries to handle them in an easy way
class ProgressBarManager:
_parent: Misc | None
_parent: Misc
_bars: Dict[str, ProgressBar] = {}

def __init__(self, parent: Misc | None):
def __init__(self, parent: Misc):
self._parent = parent

def get(self, name: str, max_value: float | None = None, initial_value: float | None = None) -> ProgressBar:
Expand All @@ -70,13 +82,17 @@ def get(self, name: str, max_value: float | None = None, initial_value: float |
return self._bars[name]

def done(self, name: str) -> bool:
if name in self._bars:
self._bars[name].destroy()
del self._bars[name]
return True
with Lock():
if name in self._bars:
self._bars[name].destroy()
del self._bars[name]
return True
return False

def update(self, name: str, value: float | None = None, max_value: float | None = None) -> ProgressBar:
def update(self, name: str, value: float | None = None, max_value: float | None = None) -> None:
self._parent.after(0, self._update, name, value, max_value)

def _update(self, name: str, value: float | None = None, max_value: float | None = None) -> ProgressBar:
bar = self.get(name, max_value=max_value, initial_value=value)
if value is None:
bar.value += 1
Expand Down
Loading