Уведомления

Группа в Telegram: @pythonsu

#1 Март 11, 2017 14:24:14

MrTrushka
Зарегистрирован: 2017-03-11
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQt5 + Threading

Проблемы с 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())

Отредактировано MrTrushka (Март 11, 2017 14:41:36)

Офлайн

#2 Март 13, 2017 07:35:18

MrViktor
Зарегистрирован: 2017-03-09
Сообщения: 83
Репутация: +  8  -
Профиль   Отправить e-mail  

PyQt5 + Threading

Странно, что у Вас не выводит ошибку, у меня вот сразу сругался (правда у меня pyQt4)

 QPixmap: It is not safe to use pixmaps outside the GUI thread
Тут мне видится проблема в том, что Вы изменяете QProgressBar из отдельного потока, точного ответа (рекомендации) дать не могу, но стоит покопаться в сторону Event(), чтоб из потока вызывать только события на изменение. Более опытные меня поправят.

Офлайн

#3 Март 13, 2017 15:48:24

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt5 + Threading

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())



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Март 13, 2017 15:56:59)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version