Как реализовать многопоточность QT5 Python

Рейтинг: 0Ответов: 1Опубликовано: 11.01.2023

После написания кода парсера фото , захотелось прикрутить графическую оболочку. И тут я столкнулся с проблемой. При выполнение кода приложение зависает пока код не выполнится до конца.

url - любой сайт с фото.

import os
import subprocess
import sys
import time
from asyncore import write
from urllib.parse import urlparse


import requests
from bs4 import BeautifulSoup
from design import Ui_Form
from PyQt5 import QtCore, QtGui, QtWidgets

app = QtWidgets.QApplication(sys.argv)

Form = QtWidgets.QMainWindow()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()

def pr ():
    
    url = ui.link.text()

    url_home = urlparse(url).hostname
    folder = ui.folder.text()

    Class_1 = ui.Class_1.text()
    Class_2 = ui.Class_2.text()

    r = requests.get(url)
    soup_ing = str(BeautifulSoup(r.content, 'lxml'))
    soup_ing = soup_ing.encode() 
    with open(".\\test.html", "wb") as file: 
        file.write(soup_ing)

    def fromSoup():
        html_file = (".\\test.html")
        html_file = open(html_file, encoding='UTF-8').read()
        soup = BeautifulSoup(html_file, 'lxml') # name of our soup
        
        link_img=[] #Создаем массив

        if not os.path.exists(folder):
            os.mkdir(folder)

        for link in soup.find_all(Class_1):
            if (link.get(Class_2) is not None):
                if ui.checkBox.isChecked():
                    link_img.append(link.get('href'))
                else:
                    link_img.append('http://' + url_home + link.get(Class_2)) #Добавляем ссылки в масив
                    #print("'" + url_home + link.get('href') + "',") #монтируем ссылку

            else:
                print('None value') #Если нет значения пишем в терминал None value
                
            f_jpg = [x for x in link_img if x.endswith('.jpg')] # Фильт по окончанию .jpg чтобы отсечь лишнее
            f_jpeg = [x for x in link_img if x.endswith('.jpeg')] # Фильт по окончанию .jpeg чтобы отсечь лишнее
            f_webp = [x for x in link_img if x.endswith('.webp')] # Фильт по окончанию .webp чтобы отсечь лишнее
            f_png = [x for x in link_img if x.endswith('.png')] # Фильт по окончанию .png чтобы отсечь лишнее
            filtered = f_jpg + f_jpeg + f_png + f_webp

        os.remove = (".\\test.html")

        for i, val in enumerate(filtered, start=1):
            print(f'• {i} => {val}')
            ui.Out_text.setText(f'• {i}')  
            Value = [i]
            
        m = 0    
        time.sleep(0.1)
        for pic_link in filtered:
            with open(folder + '\\' + pic_link.split('/')[-1], 'wb') as f:
                f.write(requests.get(pic_link).content)
                #print ("Папка с фото : " + folder + "       " + "Ссылка на файл : " + "'" + pic_link + "',")
            ui.progressBar.setMaximum(max(Value))
            m += 1
            ui.progressBar.setValue(m)
            print (m)
                
      
                    
        

            
    fromSoup()

ui.Start.clicked.connect ( pr )
ui.Start.setAutoDefault(True) #Начало скрипта по нажатию на Enter
ui.link.returnPressed.connect(ui.Start.click)
ui.Class_1.returnPressed.connect(ui.Start.click)
ui.Class_2.returnPressed.connect(ui.Start.click)
ui.folder.returnPressed.connect(ui.Start.click)



def er ():
    sys.exit()
ui.Close.clicked.connect ( er )



sys.exit(app.exec_()) 

main.py и design.py

Ответы

▲ 0

Вам необходимо для основной логики где происходит парсинг использовать QThread. Запустить выполнение основной длительной логики в оддельном потоке. При помощи QThread создать отдельную нить и там выполнять парсинг, что-бы он не мешал графической оболочке. Почитайте: https://realpython.com/python-pyqt-qthread/