Ответы пользователя по тегу Многопоточность
  • Многопоточность в Python (PyQt5)?

    @bbkmzzzz
    Все взаимодействие потоков и графики - выносить в сигналы.
    You must pass to it all the data it needs to work with
    - загружайте перед стартом все необходимые данные, если данные изменились, и воркеру надо их получить, отсылайте воркеру с помощью сигнала. Когда воркер сделал часть, результат он отсылает в сигнале.
    Весь Qt работает на сигналах, в многопоточном режиме разници не сильно много, только в том, что для взаимодействия с графикой нужно использовать только сигналы.

    UPD, у moveToThread есть особенность, все слоты класса будут выполнятьсяв отдельном потоке.
    В таком виде, как есть сейчас, вам будет очень сложно в многопоток у Qt. Классы, поля, экземпляры, общая структура приложения, система сигналов\слотов Qt, события, варианты потоков (QThread, QRunnable, QThreadPool) - про все про это надо читать и учить питон.
    Ответ написан
  • Как нормально настроить потоки в коде с использованием PyQt?

    @bbkmzzzz
    В таком виде, как приведено тут вообще работать не будет, в таком виде он даже не запустится.
    ̶Q̶T̶h̶r̶e̶a̶d̶ ̶н̶е̶ ̶н̶а̶с̶л̶е̶д̶н̶и̶к̶ ̶Q̶O̶b̶j̶e̶c̶t̶ ̶и̶ ̶н̶е̶ ̶м̶о̶ж̶е̶т̶ ̶и̶с̶п̶у̶с̶к̶а̶т̶ь̶ ̶с̶и̶г̶н̶а̶л̶ы̶. -> UPD: с определенной версии (в 5.15 точно) QThread наконец-то стал наследником QObject, так что он теперь может сам испускать сигналы. Костыль из класса сигналлера более не актуален

    Из соседнего потока нельзя вызывать изменения виджетов окна, только испуская и ловя сигналы.

    Не наследуйтесь от двух классов одновременно, огребете странностей.

    На тостере есть примеры, как в простом виде компоновать Qt.

    В общем виде, через QRunnable, выглядит так:
    import sys
    import time
    
    from PySide2.QtCore import QThreadPool, QRunnable, Signal, QObject
    from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget, QHBoxLayout
    
    
    class Main(QMainWindow):
        def __init__(self):
            super(Main, self).__init__()
            centralWidget = QWidget(self)
            self.setCentralWidget(centralWidget)
    
            # добавляем компонощик
            self.h_grid = QHBoxLayout(centralWidget)
    
            self.thread = QThreadPool().globalInstance()
            # добаляем кнопки
            self.button = QPushButton('Start thread')
            self.h_grid.addWidget(self.button)
    
            self.worker = Worker()
            self.worker.finished.connect(self.__on_finish)
    
            self.button.clicked.connect(self.start_worker)
    
        def start_worker(self):
            self.thread.start(self.worker)
    
        def __on_finish(self):
            print('Воркер закончил работу')
    
    
    class WorkerSignaller(QObject):
        finished = Signal()
    
    
    class Worker(QRunnable):
        def __init__(self):
            super(Worker, self).__init__()
            self.signaller = WorkerSignaller()
            self.finished = self.signaller.finished
    
        def run(self):
            print(f'Я воркер, и я запускаюсь')
            time_to_sleep = 10
            print(f'Я воркер, и я сплю {time_to_sleep} секунд')
            time.sleep(time_to_sleep)
            print(f'Я воркер, и я поспал')
            self.finished.emit()
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = Main()
        ex.show()
        sys.exit(app.exec_())
    Ответ написан
    Комментировать
  • PyQT5 как заставить работать ProgressBar и lcdnumber в потоке?

    @bbkmzzzz
    Доступ к виджетам возможен только из основного потока, чтобы все работало из стороннего потока шлите сигнал и подписывайтесь на него в основном потоке.
    Ответ написан
    Комментировать
  • Как запустить функцию в потоке, PYQT?

    @bbkmzzzz
    С использованием PyQt и без класса - нормально никак
    Использовать QThread или QRunnable в связке с QThreadPool
    В большом фреймворке - его инструменты
    Ответ написан
    Комментировать
  • Как передавать данные между потоками на Python?

    @bbkmzzzz
    if __name__ == '__main__': # Не понял зачем эта строка, но так работает

    При запуске файла на исполнение интерпретатор создает переменные окружения, для того файла, который запустили переменная __name__ == '__main__'. Если файл импортировали, в __name__ будет относительный путь к модулю, и в блок кода после if управление не попадет. (при импорте файл исполняется)

    multiprocessing.Queue. Это синхронизированная очередь.
    Создайте экземпляр и отдайте его каждому потоку. Поток пусть добавляет каждую итерацию расчета в список, а список потом отдает в очередь. Как только все потоки завершены, пробегаете по очереди, обрабатываете списки, делаете с ними что хотите.
    Ответ написан
    4 комментария
  • Python, как синхронизировать потоки threading?

    @bbkmzzzz
    Использовать очереди queue.Queue()
    Очередь синхронизированная. Принцип: добавляете ссылки в очередь, запускаете потоки (передаете им очереди заданий и и результатов), потоки берут задания из очереди, обрабатывают и кладут в другую очередь объект с результатом.
    Ответ написан
    Комментировать