如何在函数中使用线程来防止 gui 冻结?

How to use threading in a function to preventing gui from freezing?

我正在制作一个简单的视频音频下载器,但每当我单击下载按钮时,GUI 就会停止,直到下载完成。 我以为我可以使用线程处理这些事情,但几乎有数百种方法可以实现这一点,但我不知道我应该选择哪一种,这就是为什么我很困惑然后想问你的原因。

我的代码在这里:

import sys
import threading
import pafy
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 button - pythonspot.com'
        self.left = 100
        self.top = 100
        self.width = 320
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        button = QPushButton('Coffee shop radio', self)
        button.move(10,10)
        button.clicked.connect(self.on_click)

        self.show()

    def on_click(self):
        url = "https://www.youtube.com/watch?v=IcvruhYk0po"
        video = pafy.new(url)

        bestaudio = video.getbestaudio()
        bestaudio.download()

if __name__ == '__main__':
    app = QApplication([])
    ex = App()
    sys.exit(app.exec_())

稍微改了下代码就可以了,谢谢大家。

import sys
import threading
import pafy
from time import sleep
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot

class App(QWidget):
    threads = []

    def __init__(self):
        super().__init__()
        self.title = 'YouDio'
        self.left = 100
        self.top = 100
        self.width = 280
        self.height = 90
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        button = QPushButton('DOWNLOAD', self)
        button.move(10,25)
        button.clicked.connect(self.on_click)

        self.line = QLineEdit(self)
        self.line.move(120,27)

        self.show()

    def on_click(self):
        self.t = threading.Thread(target=self.threaded)
        self.t.start()

    def threaded(self):
        url = self.line.text()
        video = pafy.new(url)

        bestaudio = video.getbestaudio()
        bestaudio.download()

if __name__ == '__main__':
    app = QApplication([])
    ex = App()
    sys.exit(app.exec_())
from threading import Thread
import sys
import threading
import pafy
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot


def download_me():
    url = "https://www.youtube.com/watch?v=IcvruhYk0po"
    video = pafy.new(url)

    bestaudio = video.getbestaudio()
    bestaudio.download()  

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 button - pythonspot.com'
        self.left = 100
        self.top = 100
        self.width = 320
        self.height = 200
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        button = QPushButton('Coffee shop radio', self)
        button.move(10,10)
        button.clicked.connect(self.on_click)

        self.show()

    def on_click(self):
        t = Thread(target=download_me)
        t.daemon = True
        t.start()



if __name__ == '__main__':
    app = QApplication([])
    ex = App()
    sys.exit(app.exec_())

试试这个!

事实上下载任务是同步完成的,因此您的 theard 将阻塞直到下载任务结束...您必须将这部分代码放在守护线程中。

注意:我不知道 python 线程是否可以与 Qt 混合,所以你应该使用好的 Lib,但想法保持不变