Как изменить значение ProgressBar во время выполнения функции по итерациям?

Как можно обновить значение QProgressBar во время выполнения функции `mathfunc`, чтобы отображать прогресс выполнения операций? Как связать переменную `i` в функции с использованием QThread для обновления QProgressBar?
  • 21 марта 2024 г. 7:29
Ответы на вопрос 2
Для обновления значения ProgressBar во время выполнения функции можно использовать QThread, который выполнит функцию в отдельном потоке и будет отправлять сигналы о прогрессе выполнения. В примере ниже показано, как это можно сделать:

```python
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QProgressBar, QPushButton
import time

class WorkerThread(QThread):
    update_progress = pyqtSignal(int)

    def __init__(self):
        super(WorkerThread, self).__init__()

    def run(self):
        for i in range(100):
            time.sleep(0.1)  # Имитация выполнения операции
            self.update_progress.emit(i)

class MainWidget(QWidget):
    def __init__(self):
        super(MainWidget, self).__init__()

        self.progress_bar = QProgressBar(self)
        self.progress_bar.setMinimum(0)
        self.progress_bar.setMaximum(100)

        self.start_button = QPushButton('Start', self)
        self.start_button.clicked.connect(self.start_calculation)

        layout = QVBoxLayout()
        layout.addWidget(self.progress_bar)
        layout.addWidget(self.start_button)
        self.setLayout(layout)

    def start_calculation(self):
        self.progress_thread = WorkerThread()
        self.progress_thread.update_progress.connect(self.update_progress_bar)
        self.progress_thread.start()

    def update_progress_bar(self, value):
        self.progress_bar.setValue(value)

if __name__ == '__main__':
    app = QApplication([])
    widget = MainWidget()
    widget.show()
    app.exec_()
```

В этом примере создается поток `WorkerThread`, который выполняет функцию `run`, в которой происходит цикл обработки данных. При каждой итерации цикла он отправляет сигнал `update_progress` с текущим значением переменной `i`. В главном окне `MainWidget` создается ProgressBar и кнопка "Start", которая запускает функцию `start_calculation` для начала выполнения операции. Когда поток отправляет сигнал, метод `update_progress_bar` обновляет значение ProgressBar.

Надеюсь, это поможет вам обновлять значение ProgressBar во время выполнения функции по итерациям.
Добавь функции ещё один параметр - callback-функцию, которая будет вызываться каждые X итераций. 
Тогда вопрос "как подружить функцию с индикацией прогресса" сведётся к написанию подходящей callback-функции. Условно:
from time import sleep

def worker(n: int, cb=None):
    for i in range(n):
        sleep(0.2)  # работу работаем
        if cb is not None and i % 5 == 0:
            cb(i, n)  # оповещаем, если пора и если есть что
    if cb is not None:
        cb(n, n)  # последнее оповещение на 100%. можно убрать

# использование
def callback(i, n):  # callback для вывода прогресса в консоль
    print(f'{i/n:.1%}')  # выводим процент  завершения

worker(50, callback)  # работаем
Похожие вопросы