Найти - Пользователи
Полная версия: PyQt5 + Threading
Начало » GUI » PyQt5 + Threading
1
MrTrushka
Проблемы с PyQt5 и Threading. Скрипт ломается на не предсказуемом месте, а иногда, если повезет, может полностью выполниться… Я не получаю ни какой, помогающей мне, ошибки.

Создаю два ProgressBar'a, которые заполняются в 2 потока при нажатии кнопки Start.
from PyQt5.QtWidgets import QWidget, QProgressBar, QPushButton, QApplication


class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()

def initUI(self):
self.firstProgressBar = QProgressBar(self)
self.firstProgressBar.setGeometry(25, 25, 400, 40)
self.firstStep = 0

self.secondProgressBar = QProgressBar(self)
self.secondProgressBar.setGeometry(25, 100, 400, 40)
self.secondStep = 0

self.button = QPushButton("Start", self)
self.button.setGeometry(420, 25, 160, 40)

self.setGeometry(300, 300, 600, 165)


if __name__ == '__main__':
import sys
from threading import Thread

Application = QApplication(sys.argv)
ex = Example()
ex.show()

def function(pbNumber, k):
for i in range(k * 1001):
sum([i * i for i in range(5000)])

if pbNumber == 1:
ex.firstStep = i // (k * 10)
ex.firstProgressBar.setValue(ex.firstStep)
else:
ex.secondStep = i // (k * 10)
ex.secondProgressBar.setValue(ex.secondStep)

def action():
Thread(target=function, args=(1, 1)).start()
Thread(target=function, args=(2, 2)).start()

ex.button.clicked.connect(action)

sys.exit(Application.exec())
MrViktor
Странно, что у Вас не выводит ошибку, у меня вот сразу сругался (правда у меня pyQt4)
 QPixmap: It is not safe to use pixmaps outside the GUI thread
Тут мне видится проблема в том, что Вы изменяете QProgressBar из отдельного потока, точного ответа (рекомендации) дать не могу, но стоит покопаться в сторону Event(), чтоб из потока вызывать только события на изменение. Более опытные меня поправят.
PEHDOM
MrTrushka, раз уж вы используете Qt, не логичне былобы использовать QThread вместо Threading изза лучшей связи с механизмом сигналов-слотов в Qt?
Ваш пример будет выглядеть так с использованием QThread

 # -*- coding: utf-8 -*-
from PyQt4.QtGui import QWidget, QVBoxLayout, QPushButton, QProgressBar, QApplication
from PyQt4.QtCore import QThread, pyqtSignal
import sys
# наш класс потока, в котором мы переопределим ф-йиб run , чтобы она выполняла полезную работу
class MyThread(QThread):   
    progress = pyqtSignal(int) # сигнал который мы будем передавать прогрессбару
    def __init__(self,k):
        super().__init__()
        self.k = k
    def run(self): # наша функция(полезная работа), без всяких if pbNumber == 1:
          for i in range(self.k * 1001):
            sum([i * i for i in range(5000)])
            ex = i // (self.k * 10)
            self.progress.emit(ex)  # "Испускаем" сигнал и передаем в нем текщее значение прогесса
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.firstProgressBar = QProgressBar(self)
        self.firstProgressBar.setGeometry(25, 25, 400, 40)
        self.firstStep = 0
        self.secondProgressBar = QProgressBar(self)
        self.secondProgressBar.setGeometry(25, 100, 400, 40)
        self.secondStep = 0
        self.button = QPushButton("Start", self)
        self.button.setGeometry(420, 25, 160, 40)
        self.button.clicked.connect(self.action)
        self.setGeometry(300, 300, 600, 165)
    def action(self):
        self.thread1 = MyThread(1)  # создаем первый поток
        self.thread1.progress.connect(self.setFirstPbar)  #соединяем сигнал progress первого пока с ф-цией setFirstPbar
        # вобще можно сразу писать
        # self.thread1.progressed.connect(self.firstProgressBar.setValue)
        # если вам кроме изменения прогресбара ничего больше не надо
        self.thread2 = MyThread(2) #все тоже самое для второго
        self.thread2.progress.connect(self.setSecondPbar)
        self.thread1.start()
        self.thread2.start()
    def setFirstPbar(self, value):
        self.firstStep = value     # делаем какиенить действия
        self.firstProgressBar.setValue(value)  #устанавливаем значение прогрессбара1
    def setSecondPbar(self, value):  # все тоже самоме для второго пргрессбара
        self.secondStep = value
        self.secondProgressBar.setValue(value)
if __name__ == '__main__':
    Application = QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(Application.exec())
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB