Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » [PyQt] Небольшой модуль для работы с потоками [RSS Feed]

#1 Май 1, 2011 13:12:21

SkyRzn
От:
Зарегистрирован: 2011-05-01
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

[PyQt] Небольшой модуль для работы с потоками

Написал небольшой модуль, упрощающий (ну, как мне кажется :)) работу с потоками.
В двух словах: можно заставить метод класса (потомка QObject) выполняться в отдельном потоке. При этом метод может обращаться к атрибутам (ограниченно) и методам класса реентерабельно.

Пример работы с модулем:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, time
from simple_thread import SimpleThread, closeThreads

MAX = 10
BAR_COUNT = 4
class MainFrame(QFrame):
def __init__(self):
QFrame.__init__(self)

layout = QVBoxLayout(self)

self.barList = []
for i in range(BAR_COUNT):
bar = QProgressBar(self)
bar.setRange(0, MAX)
layout.addWidget(bar)
self.barList.append(bar)

button = QPushButton('Go', self)
button.clicked.connect(self.goClick)
layout.addWidget(button)

def goClick(self):
for i in range(BAR_COUNT):
self.go(i, thr_start = True)

@SimpleThread
def go(self, barNum):
for progress in range(MAX+1):
if self.thr_stopFlag:
break
self.setProgress(barNum, progress)
time.sleep(0.5)

def setProgress(self, barNum, progress):
self.barList[barNum].setValue(progress)

def closeEvent(self, event):
closeThreads()

if __name__ == "__main__":
app = QApplication(sys.argv)
mainFrame = MainFrame()
mainFrame.show()
app.exec_()
Здесь метод go обертывается декоратором @SimpleThread.
	@SimpleThread
def go(self, barNum):
for progress in range(MAX+1):
if self.thr_stopFlag:
break
self.setProgress(barNum, progress)
time.sleep(0.5)
В методе каждые 0.5 секунд увеличивается значение одного из прогрессбаров на единицу. Номер прогрессбара в списке self.barList передается аргументом barNum.

При вызове метода go
self.go(i, thr_start = True)
создается отдельный поток, в контексте которого выполняется код этого метода. Именованный аргумент thr_start запускает поток сразу же после создания.

Изменение значения прогрессбара происходит непосредственно в методе setProgress.
	def setProgress(self, barNum, progress):
self.barList[barNum].setValue(progress)
Несмотря на то, что вызов setProgress мы производим из отдельного потока, его код выполняется в контексте основного потока и не вызывает проблем с доступом к GUI.

Функция closeThreads
	def closeEvent(self, event):
closeThreads()
необходима для корректного завершения всех потоков при закрытии главного окна.

В методе, который будет выполняться в отдельном потоке, мы можем безопасно:
- вызывать другие методы класса
- получать неизменяемые аттрибуты
- получать аттрибуты типа list и dict (при этом происходит копирование значения аттрибута)
- устанавливать аттрибуты.

Хотелось бы услышать ваше мнение и прояснить несколько вопросов:
1) Не велосипед ли это? Если да, то ткните, пожалуйста, ссылкой.
2) Нужно ли это вообще? :)
3) В чем косяки?

P. S. Что-то не получается приаттачить файл. Здесь модуль и приведенный выше пример.



Отредактировано (Май 1, 2011 13:17:42)

Офлайн

  • Начало
  • » GUI
  • » [PyQt] Небольшой модуль для работы с потоками[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version