Реализация прогресса QProgressBar одного скрипта в окне второго

Описание: из окна приложения (скрипт m1.py), по кнопке, вызывается скрипт (otv.py), который отрабатывает в фоновом режиме. Процесс выполнения второго скрипта отображается в statusBar первого приложения.
На данный момент функционал реализован через третий скрипт (b1.py).

Вопрос: Как корректно передать сигнал процесса выполнения ProgressBar из второго скрипта otv.py, первому m1.py минуя третий.

P.S. В один скрипт просьба не объединять, поскольку пример схематичный и скриптов типа otv.py несколько, а m1.py перегружен.

m1.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
from PyQt5.QtCore import (QDate, QObject, QEvent, pyqtSlot, pyqtSignal, QThread,
                          QTimeLine, QTimer, QSize, QSettings, QBasicTimer)

class Thread(QtCore.QThread):
    progress_chek = pyqtSignal(int)
    finished = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.x = 0

    def run(self):
        print('m1.py > class Thread > def run >')
        while self.x <= 200:
            try:
                self.progress_chek.emit(self.x)
            except Exception as exc_emit:
                print('m1.py > class Thread > ошибка exc_emit = ', exc_emit)

            self.x += 10
            self.msleep(400)
            print()
            print('m1.py > class Thread > def run > x2 =', self.x)
        print('m1.py > class Thread > self.finished.emit()')
        self.finished.emit()

class Example(QtWidgets.QMainWindow):
    def __init__(self):
        super(Example, self).__init__()
        QtWidgets.QMainWindow.__init__(self)

        self.initUI(self)

    def initUI(self, QProgressBar):

        self.btn_dir = QtWidgets.QPushButton('Запуск')
        self.btn_dir.clicked.connect(self.ot)
        # btn_dir.clicked.connect(self.ot_v)

        self.progress = QtWidgets.QProgressBar(self, minimum=0, maximum=100)
        self.progress.setObjectName("progress")
        self.progress.setStyleSheet('text-align: center; '                                     
                       'min-height: 15px; max-height: 15px;')

        self.thread = Thread()
        try:
            self.thread.progress_chek.connect(self.update_progressbar)
            self.thread.finished.connect(self.finished_progressbar)
        except Exception as exc_t:
            print('m1.py > class Example > ошибка exc_t = ', exc_t)

        self.progressbar_self()
        self.statusBar().insertPermanentWidget(1, self.progress)
        self.statusBar().addPermanentWidget(self.btn_dir)

    def ot(self):
        print('m1.py > class Example > def ot > ')
        import otv

    def progressbar_self(self):
        print('m1.py > class Example > def progressbar_self > ')
        import b1
        b1.self = self

    def progressbar_reset(self):
        print('m1.py > class Example > def progressbar_reset > ')
        self.progress.reset()

    def signal(self, value):
        print('m1.py > class Example > def signal > ')
        print(f'прогресс процесса {value} %')
        self.progress.setValue(value)


    def update_progressbar(self, val):
        print('m1.py > class Example > def update_progressbar > ')
        try:
            self.progress.setValue(val)
        except Exception as exc_val:
            print('m1.py > class Example > ошибка exc_val = ', exc_val)


    def finished_progressbar(self):
        print()
        print('m1.py > class Example > def finished_progressbar > ')
        self.label.clear()
        msg = QtWidgets.QMessageBox.information(
            self,
            'ВНИМАНИЕ',
            'Процесс завершен - можете закрывать окно!'
        )
        self.progress.reset()

    def ot_v(self):
        print('m1.py > class Example > def ot_v > ')
        try:
            self.thread.x = 0
            self.progress.reset()
            self.progress.setValue(0)
            self.thread.start()
        except Exception as thread:
            print('m1.py > class Example > ошибка thread = ', thread)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = Example()
    ex.show()
    ex.resize(500, 300)
    sys.exit(app.exec())

otv.py

import time

from m1 import Example
from b1 import self

print()
print('_______________________________________________________')
print()

def widg_gotov():
    time.sleep(5.0)
    print('otv > обнулить ProgressBar')
    Example.progressbar_reset(self)

def while_x(x):
    while x < 200:
        x = x+10
        time.sleep(0.4)
        print('otv > def while_x > x1 =', x)

try:
    Example.ot_v(self)
except Exception as exc_ot:
    print('otv > ошибка exc_ot = ', exc_ot)

x = 0
while_x(x)
print()
widg_gotov()
print('_______________________________________________________')

b1.py

self = []

if __name__ == '__main__':
    print()

Ответы (2 шт):

Автор решения: S. Nick

Я понял так, что с Реализацией QProgressBar в потоке вы уже разобрались.

Теперь вы хотите понять как взаимодействовать с QProgressBar в основном потоке, но сам QProgressBar находится в одном модуле, а какой-то цикл с изменяемыми данными в другом модуле.

Совсем не понятно для чего вам модуль b1.py ?

Нельзя использовать time.sleep(...) в основном потоке - это замораживает интерфейс.

Вам надо познакомиться с QTimer.
Класс QTimer предоставляет повторяющиеся и однократные таймеры.

m1.py

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, QtSql
from PyQt5.QtCore import (QDate, QObject, QEvent, pyqtSlot, 
    pyqtSignal, QThread, QTimeLine, QTimer, QSize, QSettings, 
    QBasicTimer)
                          
# ??? import b1
from otv import OtvClass


class Example(QtWidgets.QMainWindow):
    def __init__(self):
        super(Example, self).__init__()

#        self.initUI(self)
        self.initUI()

#    def initUI(self, QProgressBar):
    def initUI(self):
        self.btn_dir = QtWidgets.QPushButton('Запуск')
        self.btn_dir.clicked.connect(self.ot)
        # btn_dir.clicked.connect(self.ot_v)

        self.progress = QtWidgets.QProgressBar(self, minimum=0, maximum=100)
        self.progress.setObjectName("progress")
        self.progress.setStyleSheet('text-align: center; '                                     
                       'min-height: 15px; max-height: 15px;')
        self.progress.setRange(0, 200)                                  # +++          

        self.statusBar().insertPermanentWidget(1, self.progress)
        self.statusBar().addPermanentWidget(self.btn_dir)

    def ot(self):
        print('m1.py > class Example > def ot > ')
# ???        import otv
        self.otvClass = OtvClass(self)                                   # +++
        self.btn_dir.setEnabled(False)                                   # +++
        self.otvClass.timer.start()                                      # +++


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = Example()
    ex.show()
    ex.resize(500, 300)
    sys.exit(app.exec())

otv.py

# ??? import time
# ??? from m1 import Example
# ??? from b1 import self

from PyQt5.Qt import *


class OtvClass(QObject):
    x = 0
    
    def __init__(self, parent=None):
        super(OtvClass, self).__init__(parent)
        
        self.parent = parent
        
        self.timer = QTimer()
        self.timer.setInterval(400)
        self.timer.timeout.connect(self.while_x)
    
#    def while_x(self, x):
    def while_x(self):    
        self.x += 10
        if self.x <= 200:
            self.parent.progress.setValue(self.x)
        else:
            self.timer.stop()
            self.parent.btn_dir.setEnabled(True)
        print(f'x = {self.x}') 

введите сюда описание изображения

→ Ссылка
Автор решения: Tusher

Для моего перегруженного комплекса подошел путь упрощения процесса:

# m1.py

***

def ot(self): # клик по кнопке
    thread1 = threading.Thread(target=self.progress_process, daemon=True)
    thread1.start()
    thread2 = threading.Thread(target=self.to_v)
    thread2.start()

def ot_v(self): # просто запуск выполняемого скрипта
    import otv.py

def progress_process(self): # любой счетчик
    self.y = 0
    self.progress.setValue(self.y)
    for self.y in range(1, 101):
        if self.y % 10 == 0:
            self.progress.setValue(self.y)
        if 99 > self.y > 90:
            self.progress.setValue(self.y)
            self.y = self.y + 1
***
→ Ссылка