【问题标题】:How to use threading in a function to preventing gui from freezing? [duplicate]如何在函数中使用线程来防止 gui 冻结? [复制]
【发布时间】:2020-04-15 22:48:51
【问题描述】:

我正在从视频制作一个简单的音频下载器,但是每当我单击下载按钮时,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_())

【问题讨论】:

  • 您不应覆盖现有的类属性,例如width() 和height(),因为您可能需要轻松访问它们。此外,在其 __init__ 中显示小部件通常不是一件好事,因为可见性应该是手动或交互设置的,在实例创建之后。

标签: python python-3.x multithreading pyqt5 pafy


【解决方案1】:
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_())

试试这个!

事实上下载任务是同步完成的,所以你的ardard会阻塞直到下载任务结束……你必须把这部分代码放在一个守护线程中。

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

【讨论】:

  • 虽然理论上您的答案可能是正确的,但将 python 线程与 Qt 混合通常不是一个好主意,因为 QThreads 通常被认为是更好的解决方案(主要是因为它们的整个信号/槽机制提供,但不仅如此)。
  • #musicamante 是的,对...我不是 Qt 程序员,所以...我将编辑我的帖子并附上评论
  • 明白了,谢谢!
  • @musicamante 恕我直言,在这两种情况下都可以使用线程或 QThread,实际上 QThread 是一个处理本机线程的 QObject,这就是线程。所以一般来说两者都是有效的,显然取决于具体情况,一种方法或另一种方法更方便。
  • @eyllanesc 你是对的,我应该以不同的方式说,因为它们在概念上是相同的并且在技术上以相同的方式运行,但 QThreads 通常是更好的选择,因为他们提供的与 Qt 的更好集成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多