Добавление данных из другого потока в генерируемые виджеты

Есть список данных (data), содержащий в себе различные типы объектов.

В зависимости от объекта создаётся нужный label, в который помещается объект. Некоторые объекты требуют подгрузки, и чтобы не делать запуск программы долгим я выношу их в отдельные потоки.

Как сделать так, чтобы подгрузившиеся данные вносились в тот же самый label, который создался в цикле, в котором этот поток был запущен, чтобы лэйблы шли по очереди списка.

# -*- coding: utf-8 -*-
from PyQt5 import QtWidgets
import sys
from PyQt5.QtCore import Qt
from PyQt5 import QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QLabel, QVBoxLayout, QScrollArea
from threading import Thread
import requests
from bs4 import BeautifulSoup as bs

class MyWin(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self.vbox = QVBoxLayout()
        self.vbox.addStretch(1)


        data = ['https://ru.stackoverflow.com/', 'some', 'https://yandex.kz/', 'https://www.coronavirus2020.kz/', 'words', 'https://youtube.com', 'in', 'https://yandex.kz/', 'this', 'https://vk.com/', 'list', 'https://google.kz/']

        for i in data:
            if i.startswith('http'):
                digit_label = QLabel()

                Thread(target=self.parse_func, args=(i, 'success')).start()
                self.vbox.addWidget(digit_label)

            else:
                text_label = QLabel()
                text_label.setText(i)
                self.vbox.addWidget(text_label)


        self.scrollarea = QScrollArea(self)
        self.scrollarea.resize(self.width(), self.height())
        self.area = QWidget()
        self.area.setLayout(self.vbox)
        self.scrollarea.setWidget(self.area)

    def parse_func(self, url, string):
        page = requests.get(url)
        soup = bs(page.text, "html.parser")
        news = soup.find("title")
        news = str(news).replace('<title>', '')
        news = news.replace('</title>', '').lower()

        digit_label.setText(news)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MyWin()
    w.show()
    sys.exit(app.exec_())


Ответы (1 шт):

Автор решения: S. Nick

Попробуйте так:

import sys
from PyQt5 import QtWidgets,  QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QLabel, QVBoxLayout, QScrollArea
from threading import Thread
import requests
from bs4 import BeautifulSoup as bs


class MyWin(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()

        self.vbox = QVBoxLayout()
        self.vbox.addStretch(1)

        data = ['https://ru.stackoverflow.com/', 
                'some', 
#                'https://yandex.kz/', 
#                'https://www.coronavirus2020.kz/', 
                'words', 
                'https://youtube.com', 
                'in', 
#                'https://yandex.kz/', 
                'this', 
#                'https://vk.com/', 
                'list', 
#                'https://google.kz/'
                'https://www.google.com/'
                ]

        for i in data:
            if i.startswith('http'):
                digit_label = QLabel(f'digit_label {i}')

# +++                                                              vvvvvvvvvvv
                Thread(target=self.parse_func, args=(i, 'success', digit_label)).start()
                self.vbox.addWidget(digit_label)

            else:
                text_label = QLabel()
                text_label.setText(i)
                self.vbox.addWidget(text_label)


        self.scrollarea = QScrollArea(self)
        self.scrollarea.resize(self.width(), self.height())      
        self.area = QWidget()
        self.area.setLayout(self.vbox)
        self.scrollarea.setWidget(self.area)

# +++                                 vvvvv
    def parse_func(self, url, string, label):
        page = requests.get(url)
        soup = bs(page.text, "html.parser")
        news = soup.find("title")
        news = str(news).replace('<title>', '')
        news = news.replace('</title>', '').lower()

#        digit_label.setText(news)
        if news:
            print(f'news - {news}\n\n')
            label.setText(news)                                # +++


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MyWin()
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка