Andy_Scull

PyQt + Threading

09.07.2012, 12:48. Показов 2978. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день, и в гуи и в трединге я нуб, с инета скопипастил и модифицировал тестовый пример, который запускает обработку в фоновом треде и не блокирует гуи.
Буду раз, если кто сможет ответить на вопросы -
1. вообще такое воплощение идеи жизнеспособно? В будущем я хочу приделать гуи к своей проге-даунлоадеру, чтобы выводила текущий прогресс закачек.
2. где лучше создавать в моем коде pbar - в __init__ workerThread'а, или как сейчас в основной функции? Пока что не смотрел детальную документацию, насколько понимаю у QThread только метод run() запускается в новом треде.
3. как-то криво вышло удаление отработавшего прогрессбара, подскажите как и откуда его лучше удалять? Сойдет ли то, как сейчас сделано (обращение из фонового треда), поскольку он все равно удаляется?
В будущем думаю для этого надо делать обработку баров в основной функции, она будет их размещать, чтобы не накладывались, масштабировать окно итп, соответственно должна держать лист с текущими барами, и добавлять/удалять в него.
Как ещё вариант, поскольку в моем даунлоадере задается число потоков скачивания, можно сделать массив баров и реюзать/хайдить их.
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import sys
import threading
import time
from PyQt4 import QtGui, QtCore
 
class Example(QtGui.QWidget):
    
    def __init__(self):
        super(Example, self).__init__()
        self.workers=[]
        self.initUI()
        
    def initUI(self):      
        self.btn = QtGui.QPushButton('Start', self)
        self.btn.move(40, 80)
        self.btn.clicked.connect(self.doAction)
        self.setGeometry(300, 300, 280, 170)
        self.setWindowTitle('QtGui.QProgressBar')
        self.show()
        
    def doAction(self):
        pbar = QtGui.QProgressBar(self)
        pbar.setGeometry(30, 40, 200, 25)
        pbar.show()
 
        worker = workerThread(pbar)
        self.workers.append(worker)
        pbar.connect(worker,QtCore.SIGNAL('update(int)'),pbar.setValue)
        worker.start()
 
 
class workerThread(QtCore.QThread):
    def __init__(self,pbar):
        QtCore.QThread.__init__(self)
        self.pbar = pbar 
 
    def __del__(self):
        self.wait()
 
    def run(self):
        for n in range(10):
            print(n)
            time.sleep(0.5)
            self.emit(QtCore.SIGNAL("update(int)"),n)
        self.pbar.deleteLater()
        self.pbar = None
 
def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
 
 
if __name__ == '__main__':
    main()
Добавлено через 1 час 11 минут
В общем, выходит каменный цветок, очень коряво, но сама идея работает.
По кнопке запускается тред, который резервирует для вывода один из прогрессбаров.
По окончании процесса бар освобождается и скрывается.
Пока что буду доводить до ума эту систему, скажите, если подметите явные ляпы.
Параметр text везде подразумевает идентификатор рабочего процесса. Можно использовать и номер.
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import sys
import threading
import time
from PyQt4 import QtGui, QtCore
 
class DLStack:
    def __init__(self,gui,number):
        self.data=[]
        self.map={"":0}
        self.number=number
        for n in range(number):
            pb=QtGui.QProgressBar(gui)
            pb.setGeometry(30,20+n*25,200,25)
            tx=QtGui.QLabel(gui)
            tx.setGeometry(0,20+n*25,40,25)
            self.data.append([pb,tx,""])
 
    def link(self,text,worker):
        if (not text in self.map.keys()) and ("" in self.map.keys()):
            n=self.map[""]
            self.data[n][2]=text
            self.data[n][1].setText(text)
            self.data[n][0].setValue(0)
            self.data[n][0].connect(worker,QtCore.SIGNAL('update(int)'),self.data[n][0].setValue)
            self.data[n][0].connect(worker,QtCore.SIGNAL('finished(QString)'),self.unlink)
            self.data[n][1].show()
            self.data[n][0].show()
            self.map[text]=n
            for i in range(self.number):
                if self.data[i][2]=="":
                    self.map[""]=i
                    break
            else:
                del self.map[""]
 
            return(self.data[n][1])
        else:
            return(None)
 
    def unlink(self,text):
        for n in range(self.number):
            if self.data[n][2]==text:
                self.data[n][0].hide()
                self.data[n][1].hide()
                self.data[n][2]=""
                self.map[""]=n
                del self.map[text]
                return True
        else:
            return False
 
class Example(QtGui.QWidget):
    
    def __init__(self,maxnum):
        super(Example, self).__init__()
        self.workers=[]
        self.maxdl=maxnum
        self.dl=DLStack(self,self.maxdl)
        self.initUI()
        self.n=0
        
    def initUI(self):
        self.btn = QtGui.QPushButton('Start', self)
        self.btn.move(40, 40+self.maxdl*25)
        self.btn.clicked.connect(self.doAction)
        self.setGeometry(300, 300, 280, 100+self.maxdl*25)
        self.setWindowTitle('QtGui.QProgressBar')
        self.show()
        
    def doAction(self):
        text="test"+str(self.n)
        worker = workerThread(text)
        self.workers.append(worker)
        if self.dl.link(text,worker)!=None:
            worker.start()
            self.n+=1
        else:
            del worker
 
class workerThread(QtCore.QThread):
    def __init__(self,text):
        QtCore.QThread.__init__(self)
        self.text=text
 
    def __del__(self):
        self.wait()
 
    def run(self):
        for n in range(10):
            print(n)
            time.sleep(0.5)
            self.emit(QtCore.SIGNAL("update(int)"),n)
        self.emit(QtCore.SIGNAL("finished(QString)"),self.text)
 
def main():
    app = QtGui.QApplication(sys.argv)
    ex = Example(10)
    sys.exit(app.exec_())
 
 
if __name__ == '__main__':
    main()
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.07.2012, 12:48
Ответы с готовыми решениями:

Разница между PyQT 5 и PyQT 6
Добрый день, форумчане. Прошел тут курс всеми вами любимого автора, познакомился с GUI TKinter, и по вашим советам решил освоить PyQT. ...

Из QT в PyQt
Здравствуйте, подскажите правильно ли у меня получился перевод из QT в PyQt? Интересует именно выполнение класса QCoreApplication и...

PyQt классы
Всем привет. Такой вопрос назрел. Вот создал я через QtDesigner форму. Сделала из ui класс на python. получилось # -*- coding: utf-8 -*- ...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.07.2012, 12:48
Помогаю со студенческими работами здесь

Лицензия PyQt
На странице https://pypi.org/project/PyQt6/ написано в переводе на русский PyQt6 выпускается под лицензией GPL v3 и под коммерческой...

PyQt и C++ виджеты
Как прикрутить в библиотеку PyQt сторонние Qt виджеты, написанные на C++?

PyQT+OpenCV
Имеется следующий код, который работает в консоли (распознавание номерных знаков) class Video(): cap = cv2.VideoCapture(0) ...

SetText в PyQt
Привет. Появилась такая проблема. Когда в цикле хочу установить значение в QLineEdit c помощью setText(), то значение по ходу цикла не...

Python + PyQt
Добрый вечер. Столкнулся со следующей проблемой. Создать всплывающую подсказку для шапки QTableWidget не составило труда через...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru