0

I'm making a simple audio downloader from video,but whenever i click download button gui stops until downloading has finished. I thought i can use threading for kind of these things but almost there are hundreds of method to achieve that,but i don't know which one i should choose and that's why I'm so confused then wanted to ask you.

My code here:

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_())

Have changed the code a little and it works,thanks for everyone.

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_())
  • 1
    You shouldn't overwrite existing class properties such as [`width()`](https://doc.qt.io/qt-5/qwidget.html#width-prop) and [`height()`](https://doc.qt.io/qt-5/qwidget.html#height-prop), as you might need to access them easily. Also, showing a widget within its `__init__` is not usually a good thing to do, as the visibility should be something that is set manually or interactively, *after* the instance is created. – musicamante Apr 15 '20 at 23:42

1 Answers1

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_())

try this!

In fact download task is done synchronously so your theard will block until the download task is over...you have to put this part of your code inside a daemon thread.

Note: I don't know if python thread can be mixed with Qt so you should use the good Lib but the idea remains the same

  • 1
    While, theoretically, your answer may be correct, it's usually not a good idea to mix python threads with Qt, as QThreads are commonly considered a better solution (mostly because of the whole signal/slot mechanism they offer, but not only). – musicamante Apr 15 '20 at 23:38
  • 1
    #musicamante yes right...I'm not a Qt programmer so...I will edit my post with remark thanks – Narcisse Doudieu Siewe Apr 15 '20 at 23:41
  • got the idea,thank you ! – ShooterLens Aim Apr 15 '20 at 23:45
  • 1
    @musicamante IMHO using threading or QThread can be used in both cases, actually QThread is a QObject that handles a native thread which is what threading is. So in general both are valid, obviously depending on the particular case one method or the other is more convenient. – eyllanesc Apr 16 '20 at 00:08
  • @eyllanesc You're right, I should have said that in a different way, as they're conceptually the same thing and technically behave in the same way, but QThreads are normally the better choice because of the better integration they offer with Qt. – musicamante Apr 16 '20 at 16:36