Search code examples
pythonpyqtpyqt4youtube-dl

How to output youtube-dl log to Pyqt textbox


I tried to create a simple PyQt Gui to download youtube videos using urls. Everything works fine, except for the part where i want to output the log of youtube-dl in a textbox in PyQt. Nothing shows up in the textbox when i do this.

I created a class called MyLogger():

class MyLogger(object):

    def debug(self, msg):
        GUI.e2.setText(str(msg))


    def warning(self, msg):
        GUI.e2.setText(str(msg))


    def error(self, msg):
        GUI.e2.setText(str(msg))

This class is passed to youtube_dl.YoutubeDL using ydl_opts:

ydl_opts = {'format':'140','logger':MyLogger()}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    ydl.download([url])

GUI is an instance of QtGui.QMainWindow and e2 is an instance of QtGui.QLineEdit()

Any help with why this is not working, or maybe other ways to do this, is appreciated. Thanks!


Solution

  • First, the download must be executed in another thread since this task is very time consuming blocking the main thread.

    On the other hand I think that a better option is to use a QTextEdit instead of a QLineEdit since it can show many lines of information.

    To send a data you could use signals as I show below:

    import sys
    
    from PyQt4 import QtCore, QtGui
    import youtube_dl
    
    
    class MyLogger(QtCore.QObject):
        messageSignal = QtCore.pyqtSignal(str)
        def debug(self, msg):
            self.messageSignal.emit(msg)
    
        def warning(self, msg):
            self.messageSignal.emit(msg)
    
        def error(self, msg):
            self.messageSignal.emit(msg)
    
    
    class YoutubeDownload(QtCore.QThread):
        def __init__(self, url, ydl_opts, *args, **kwargs):
            QtCore.QThread.__init__(self, *args, **kwargs)
            self.url = url
            self.ydl_opts = ydl_opts
    
        def run(self):
            with youtube_dl.YoutubeDL(self.ydl_opts) as ydl:
                ydl.download([self.url])
    
    
    class Widget(QtGui.QMainWindow):
        def __init__(self, *args, **kwargs):
            QtGui.QMainWindow.__init__(self, *args, **kwargs)
            self.centralWidget = QtGui.QWidget()
            self.setCentralWidget(self.centralWidget)
            lay = QtGui.QVBoxLayout(self.centralWidget)
            url = "https://www.youtube.com/watch?v=R6zWLfHIYJw"
            self.urlLineEdit = QtGui.QLineEdit(url)
            self.messageTE = QtGui.QTextEdit()
            lay.addWidget(self.urlLineEdit)
            lay.addWidget(self.messageTE)
            self.urlLineEdit.editingFinished.connect(self.onEditingFinished)
    
        def onEditingFinished(self):
            url = str(self.urlLineEdit.text())
            if url != "":
                logger = MyLogger()
                logger.messageSignal.connect(self.messageTE.append)
                ydl_opts = {'format':'140','logger': logger}
                self.thread = YoutubeDownload(url, ydl_opts)
                self.thread.start()
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        w = Widget()
        w.show()
        sys.exit(app.exec_())