Как обновлять label в pyqt5 из другого процесса?
У меня есть 2 процесса:
- один это парсер;
- другой pyqt UI.
Парсер получает новые данные раз в 5 секунд. И эти данные нужно отображать и обновлять в label.
У меня не получается отображение и обновление данных для label.
import time
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QVBoxLayout, QMainWindow, QApplication, \
QLabel, QWidget
from PyQt5.QtGui import QPixmap, QPalette
from PyQt5.QtCore import Qt, QObject, QThread
import sys
import random
from multiprocessing import Process
class UiMainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(362, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.listWidget = QtWidgets.QListWidget(self.centralwidget)
self.listWidget.setGeometry(QtCore.QRect(10, 10, 336, 192))
self.listWidget.setObjectName("listWidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(20, 270, 331, 200))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(10, 470, 141, 31))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Twitch"))
self.pushButton.setText(_translate("MainWindow", "Закрыть"))
class Thread(QtCore.QThread):
updateSignal = QtCore.pyqtSignal(str)
def __init__(self, status, parent=None):
super(Thread, self).__init__(parent)
self.status = status
def run(self):
self.updateSignal.emit(f'{self.status}')
self.msleep(1000)
class MainWindow(QMainWindow, UiMainWindow):
def __init__(self, streamers_links, status):
super().__init__()
self.setupUi(self)
self.streamers_links = streamers_links
self.status = status
self.pushButton.clicked.connect(self.exit)
for links in range(len(self.streamers_links)):
item = QtWidgets.QListWidgetItem()
self.listWidget.addItem(item)
__sortingEnabled = self.listWidget.isSortingEnabled()
_translate = QtCore.QCoreApplication.translate
item = self.listWidget.item(links)
item.setText(_translate("MainWindow", self.streamers_links[links]))
self.listWidget.setSortingEnabled(__sortingEnabled)
def statusUpgrader(self, status):
self.label.setText(status)
def exit(self):
#os.system("TASKKILL /F /IM chromedriver.exe")
#os.system("TASKKILL /F /IM chrome.exe")
raise SystemExit(1)
def start_thread(self, status):
self.thread = Thread(status)
self.thread.updateSignal.connect(self.statusUpgrader)
self.thread.start()
streamers_links = [
'https://www.twitch.tv/rainbow6',
'https://www.twitch.tv/r6esportsbr2',
'https://www.twitch.tv/rainbow6fr',
'https://www.twitch.tv/rainbow6de',
'https://www.twitch.tv/rainbow6es',
'https://www.twitch.tv/rainbow6jp'
]
def gui(streamer_links):
app = QApplication(sys.argv)
w = MainWindow(streamers_links, '')
w.show()
sys.exit(app.exec())
def starter(streamers_links):
# допустим это парсер, который получает значения раз в 5 секунд
for i in range(len(streamers_links)):
checker = random.randint(1, 2)
if checker == 1:
status = streamers_links[i] + ' онлайн'
print(status)
else:
status = streamers_links[i] + ' не в сети'
print(status)
MainWindow.start_thread(self, status)
time.sleep(5)
if __name__ == '__main__':
twitch_p = Process(target=starter, args=(streamers_links,))
gui_p = Process(target=gui, args=(streamers_links,))
twitch_p.start()
gui_p.start()
twitch_p.join()
gui_p.join()
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Взаимодействовать с виджетами можно только в основном потоке.
Тяжелые задачи, например парсер, выполняются в дополнительном потоке.
Взаимосвязь между потоками осуществляется посредством Signals & Slots
Сигналы и слоты используются для связи между объектами. Механизм сигналов и слотов - это центральная особенность Qt и, вероятно, часть, которая больше всего отличается от функций, предоставляемых другими фреймворками...
import sys
import random
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
#import time
#from multiprocessing import Process
class UiMainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(362, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.listWidget = QtWidgets.QListWidget(self.centralwidget)
self.listWidget.setGeometry(QtCore.QRect(10, 10, 336, 192))
self.listWidget.setObjectName("listWidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(20, 270, 331, 200))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(10, 470, 141, 31))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Twitch"))
self.pushButton.setText(_translate("MainWindow", "Закрыть"))
class Thread(QThread):
updateSignal = QtCore.pyqtSignal(str, str) # !!!
def __init__(self, streamers_links):
super().__init__()
self.streamers_links = streamers_links
self.len_streamers_links = len(self.streamers_links)
def run(self):
num_link = 0
self.msleep(1000)
while True:
# допустим это парсер, который получает значения раз в 5 секунд
checker = random.randint(1, 2)
if checker == 1:
status = 'онлайн'
else:
status = 'не в сети'
self.updateSignal.emit(self.streamers_links[num_link], status) # !!!
self.msleep(1000 * 5) # 5 сек., установите нухную вам паузу
num_link += 1
if num_link == self.len_streamers_links:
num_link = 0
class MainWindow(QMainWindow, UiMainWindow):
def __init__(self, streamers_links):
super().__init__()
self.setupUi(self)
self.streamers_links = streamers_links
self.pushButton.clicked.connect(self.close)
self.listWidget.setSelectionMode(QListWidget.SingleSelection)
self.thread = Thread(self.streamers_links)
self.thread.updateSignal.connect(self.selectItem) # !!!
self.thread.start()
for link in self.streamers_links:
item = QtWidgets.QListWidgetItem(link)
self.listWidget.addItem(item)
def selectItem(self, _link, status): # !!!
self.label.setText(f'{_link} -> {status}')
_items = self.listWidget.findItems(_link, Qt.MatchExactly)
for item in _items:
item.setSelected(True)
streamers_links = [
'https://www.twitch.tv/rainbow6',
'https://www.twitch.tv/r6esportsbr2',
'https://www.twitch.tv/rainbow6fr',
'https://www.twitch.tv/rainbow6de',
'https://www.twitch.tv/rainbow6es',
'https://www.twitch.tv/rainbow6jp'
]
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow(streamers_links)
w.show()
sys.exit(app.exec_())
