class ProgressBar(QWidget): def __init__(self, parent=None) -> None: super().__init__(parent) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.pbar = QProgressBar() self.description_label = QLabel() self.eta_label = QLabel() layout = QHBoxLayout() layout.addWidget(self.description_label) layout.addWidget(self.pbar) layout.addWidget(self.eta_label) self.setLayout(layout) def setRange(self, min, max): self.pbar.setRange(min, max) def _set_value(self, value): self.pbar.setValue(value) QApplication.processEvents() def _get_value(self): return self.pbar.value() def _set_description(self, desc): self.description_label.setText(desc) QApplication.processEvents() def _set_eta(self, eta): self.eta_label.setText(eta)
class QtLabeledProgressBar(QWidget): """QProgressBar with QLabels for description and ETA.""" def __init__(self, parent: Optional[QWidget] = None, prog: progress = None) -> None: super().__init__(parent) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.progress = prog self.qt_progress_bar = QProgressBar() self.description_label = QLabel() self.eta_label = QLabel() base_layout = QVBoxLayout() pbar_layout = QHBoxLayout() pbar_layout.addWidget(self.description_label) pbar_layout.addWidget(self.qt_progress_bar) pbar_layout.addWidget(self.eta_label) base_layout.addLayout(pbar_layout) line = QFrame(self) line.setObjectName("QtCustomTitleBarLine") line.setFixedHeight(1) base_layout.addWidget(line) self.setLayout(base_layout) def setRange(self, min, max): self.qt_progress_bar.setRange(min, max) def setValue(self, value): self.qt_progress_bar.setValue(value) QApplication.processEvents() def setDescription(self, value): if not value.endswith(': '): value = f'{value}: ' self.description_label.setText(value) QApplication.processEvents() def _set_value(self, event): self.setValue(event.value) def _get_value(self): return self.qt_progress_bar.value() def _set_description(self, event): self.setDescription(event.value) def _make_indeterminate(self, event): self.setRange(0, 0) def _set_eta(self, event): self.eta_label.setText(event.value) def _set_total(self, event): self.setRange(0, event.value)
class ProgressBar(QWidget): style = """ QProgressBar { border: 2px solid grey; border-radius: 5px; text-align: center; } """ def __init__(self, parent=None, title=None, minimum=0, maximum=1, value=0): super(ProgressBar, self).__init__(parent) layout = QGridLayout(self) self.progressbar = QProgressBar(self) self.progressbar.setMinimum(minimum) self.progressbar.setMaximum(maximum) self.progressbar.setValue(value) self.progressbar.setStyleSheet(self.style) self.label = QLabel("") self.label.setStyleSheet("Qlabel { font-size: 20px }") self.label.setAlignment(QtCore.Qt.AlignCenter) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setFixedSize(256, 64) # self.progressbar.setValue(1) layout.addWidget(self.progressbar, 0, 0) layout.addWidget(self.label, 0, 0) self.setLayout(layout) if title: self.setWindowTitle(title) def setValue(self, value): self.progressbar.setValue(value) def setMaximumValue(self, value): self.progressbar.setMaximum(value) def incrementValue(self, increment=1): self.progressbar.setValue(self.progressbar.value() + increment) def onStart(self): self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) self.show() # self.setWindowState(self.windowState() | QtCore.Qt.WindowActive) def onFinished(self): self.hide() def updateIndicatorText(self, string): self.label.setText(string)
class MemoryView(QWidget): set_value = Signal(int, float, float) """ Initializes and updates the view of memory(progress) bar. """ def __init__(self, parent): super(MemoryView, self).__init__(parent) self.critical = CRITICAL_PERCENTAGE self.memory_bar = QProgressBar(self) self.memory_bar.setAlignment(Qt.AlignCenter) self.set_value.connect(self._set_value) def set_bar_color(self, current_value: int, new_value: int): """ Updates the memory(progress) bar style if needed :param current_value: Used system memory in percentage from previous update :param new_value: Latest used system memory in percentage """ if from_normal_to_critical(self.critical, current_value, new_value): self.memory_bar.setStyleSheet(CRITICAL_STYLE) elif from_critical_to_normal(self.critical, current_value, new_value): self.memory_bar.setStyleSheet(NORMAL_STYLE) else: pass def invoke_set_value(self, new_value: int, mem_used: float, mem_avail: float): self.set_value.emit(new_value, mem_used, mem_avail) @Slot(int, float, float) def _set_value(self, new_value, mem_used, mem_avail): """ Receives memory usage information passed by memory presenter and updates the displayed content as well as the style if needed :param new_value: Latest used system memory in percentage :param mem_used: Used system memory in Gigabytes(GB) :param mem_avail: Available system memory in GB """ # newValue is the latest mem_used_percent current_value = self.memory_bar.value() if current_value == new_value: return self.set_bar_color(current_value, new_value) self.memory_bar.setValue(new_value) display_str = f"{mem_used:3.1f}/{mem_avail:3.1f} GB ({new_value:d}%)" self.memory_bar.setFormat(display_str)
class ProgressBar(QWidget): """QProgressBar with QLabels for description and ETA.""" def __init__(self, parent=None) -> None: super().__init__(parent) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.pbar = QProgressBar() self.description_label = QLabel() self.eta_label = QLabel() base_layout = QVBoxLayout() pbar_layout = QHBoxLayout() pbar_layout.addWidget(self.description_label) pbar_layout.addWidget(self.pbar) pbar_layout.addWidget(self.eta_label) base_layout.addLayout(pbar_layout) line = QFrame(self) line.setObjectName("QtCustomTitleBarLine") line.setFixedHeight(1) base_layout.addWidget(line) self.setLayout(base_layout) def setRange(self, min, max): self.pbar.setRange(min, max) def _set_value(self, value): self.pbar.setValue(value) QApplication.processEvents() def _get_value(self): return self.pbar.value() def _set_description(self, desc): self.description_label.setText(desc) QApplication.processEvents() def _set_eta(self, eta): self.eta_label.setText(eta)
class ProgressDialog(QDialog): """Progress dialog. Parameters ---------- label - string or list of strings task - QThread or list of QThread (implementing task interface) parent - QObject """ canceled = Signal() def __init__(self, label, task, parent=None): """Constructor.""" super().__init__(parent) self._label = label self._task = task if (isinstance(self._label, (list, tuple)) and isinstance(self._task, (list, tuple)) and len(self._label) == len(self._task)) or \ (isinstance(self._label, str) and isinstance(self._task, QThread)): pass else: raise ValueError() self._setup_ui() def _setup_ui(self): self.layout = QVBoxLayout() self.dlg_label = QLabel(self) self.cur_item_label = QLabel(self) self.progress_bar = QProgressBar(self) self.cancel = QPushButton('Cancel', self) self.layout.addWidget(self.dlg_label) self.layout.addWidget(self.cur_item_label) self.layout.addWidget(self.progress_bar) self.layout.addWidget(self.cancel) self.setLayout(self.layout) # Set initial value self.progress_bar.setValue(0) # Set progress bar limits and connect signals self.progress_bar.setMinimum(0) if hasattr(self._task, '__iter__'): self.dlg_label.setText(self._label[0]) self._task[0].currentItem.connect(self.cur_item_label.setText) self._task[0].itemDone.connect(self.inc_value) pb_max = self._task[0].size() for i in range(1, len(self._task)): self._task[i].currentItem.connect(self.cur_item_label.setText) self._task[i].itemDone.connect(self.inc_value) self._task[i - 1].completed.connect(self._update_label) self._task[i - 1].completed.connect(self._task[i].start) pb_max += self._task[i].size() self.progress_bar.setMaximum(pb_max) self._task[-1].completed.connect(lambda: self._exit_dlg(1)) else: self.dlg_label.setText(self._label) self._task.currentItem.connect(self.cur_item_label.setText) self._task.itemDone.connect(self.inc_value) self._task.completed.connect(lambda: self._exit_dlg(1)) self.progress_bar.setMaximum(self._task.size()) self.cancel.pressed.connect(self.canceled.emit) self.canceled.connect(lambda: self._exit_dlg(0)) self.progress_bar.valueChanged.connect(self._is_finished) def _update_label(self): next_idx = self._label.index(self.dlg_label.text()) + 1 if next_idx < len(self._label): self.dlg_label.setText(self._label[next_idx]) def _exit_dlg(self, result): if hasattr(self._task, '__iter__'): for task in self._task: task.exit_task() self._wait_task(self._task[-1]) self._task[-1].deleteLater() else: self._task.exit_task() self._wait_task(self._task) self._task.deleteLater() if result == 1: self.accept() elif result == 0: self.reject() def _wait_task(self, task): init = time.time() try: while task.isRunning(): time.sleep(0.1) if time.time() - init > 10: self._exit_dlg(0) raise Exception('Thread will not leave') except RuntimeError: pass def _is_finished(self): if self.progress_bar.value() == self.progress_bar.maximum(): self._exit_dlg(1) def set_value(self, value): """Set progress bar value.""" self.progress_bar.setValue(value) def inc_value(self): """Increase value.""" self.progress_bar.setValue(self.progress_bar.value()+1) def exec_(self): """Override.""" if hasattr(self._task, '__iter__'): self._task[0].start() else: self._task.start() return super().exec_()