problem in PyQt4 program

abhijangda

Padawan
Hello everyone, I have started creating a Download Manager for Linux using Python with PyQt4 as GUI toolkit and PycURL as library for downloading files. My problem is that whenever I start a download GUI stops. It works in the background and just keeps on downloading but no response from GUI.
Code is Here.

main.py
Code:
    from PyQt4 import QtCore,QtGui
    import downloadclass,winaddnew,treeitem
    import sys

    class Downloader(QtGui.QMainWindow):

        def __init__(self,parent=None):

            QtGui.QMainWindow.__init__(self,parent)

            self.setWindowTitle("Download")
            self.setGeometry(10,10,600,400)
         
            self.tablewidget = QtGui.QTableWidget(self)
            self.setCentralWidget(self.tablewidget)
            self.tablewidget.setColumnCount(6)
            self.tablewidget.setHorizontalHeaderLabels(['File Name','Url','Size','Downloaded','Time Remaining','Speed','Status'])
            self.tablewidget.setRowCount(1)
            self.tablewidgetrowitemarray = []
                                                       
            self.tablewidget.horizontalHeader().setClickable(False)
            self.tablewidget.cellClicked.connect(self.cellclicked)

            menubar = self.menuBar()
            newdownload = QtGui.QAction("Create a new download",self)
            start = QtGui.QAction("Start",self)
            stop = QtGui.QAction("Stop",self)
            pauseresume = QtGui.QAction("Pause/Resume",self)
            startall = QtGui.QAction("Start All",self)
            stopall = QtGui.QAction("Stop All",self)
            pauseresumeall = QtGui.QAction("Pause/Resume All",self)
            restart = QtGui.QAction("Restart Download",self)
           
            downloadmenu = menubar.addMenu("Download")
            downloadmenu.addAction(newdownload)
            downloadmenu.addAction(start)
            downloadmenu.addAction(stop)
            downloadmenu.addAction(pauseresume)
            downloadmenu.addAction(startall)
            downloadmenu.addAction(stopall)
            downloadmenu.addAction(pauseresumeall)
            downloadmenu.addAction(restart)

            self.addwin = winaddnew.addnewwin()
           
            self.url = ''
            self.path = ''
            self.filename = ''
            self.rowselected = 0
           
            self.downloaditem = treeitem.downloaditem
            self.dwlclass = downloadclass.downloadfile
            self.downloaditemarray = []
           
            self.connect(newdownload,QtCore.SIGNAL('triggered()'),self.funcshowaddwin)
            self.connect(start,QtCore.SIGNAL('triggered()'),self.funcstart)
               
            self.Timer = QtCore.QTimer(self)
            self.Timer.setInterval(200)
            self.connect(self.Timer, QtCore.SIGNAL('timeout()'),self.functimer)
           
        def cellclicked(self,row,col):

            self.tablewidget.selectRow(row)
            self.rowselected = row

        def funcshowaddwin(self):

            self.Timer.start()
            self.addwin.show()
       
        def functimer(self):

            self.url,self.path = self.addwin.funcpass()
            if self.url != '':
                if self.path !='':
                    self.Timer.stop()
                    self.adddownload()

        def adddownload(self):

            self.downloaditemarray.append(self.downloaditem(self.getfilename(self.url),self.url,0,'Downloading'))
            self.createrow(self.downloaditemarray[len(self.downloaditemarray)-1])

        def createrow(self,downloaditem):

            for i in range(0,6):
                self.tablewidgetrowitemarray.append(QtGui.QTableWidgetItem(0))
                self.tablewidgetrowitemarray[i].setFlags(QtCore.Qt.ItemIsSelectable)
                self.tablewidget.setItem(0,i,self.tablewidgetrowitemarray[i])

            self.tablewidgetrowitemarray[0].setText(downloaditem.filename)
            self.tablewidgetrowitemarray[1].setText(downloaditem.url)
            self.tablewidgetrowitemarray[2].setText(str(downloaditem.size))
            self.tablewidgetrowitemarray[3].setText("")
            self.tablewidgetrowitemarray[4].setText("")
            self.tablewidgetrowitemarray[5].setText("")
            #self.tablewidgetrowitemarray[6].setText(downloaditem.status)
           
        def getfilename(self,url):

            lst = url.split('/')
            return lst[len(lst)-1]

        def funcstart(self):

            d = self.dwlclass(self.path,str(self.tablewidget.item(self.rowselected,1).text()),self.tablewidget.item(self.rowselected,2).text())
            self.tablewidgetrowitemarray[2].setText(str(d.size))
            d.start()
           
           
    app = QtGui.QApplication(sys.argv)
    d = Downloader()
    d.show()
    app.exec_()

downloadclass.py

Code:
    import pycurl,os

    class downloadfile(object):

        def __init__(self,path,url,downloaded):

            self.url = url
            self.path = path
            self.downloaded = downloaded
            self.size = 0
            self.bytesdownloaded = 0
            self.initial = 0
            self.final = 0
           
            self.curl = pycurl.Curl()
            self.curl.setopt(pycurl.URL,self.url)
                   
        def progress(self,download_t,download_d,upload_t,upload_d):

            self.initial = download_d
            self.size = download_t
            self.bytesdownloaded = download_d
            self.speed = self.final - self.initial
            self.final = download_d
           
        def start(self):
           
            f = open(self.path,"wb")
            self.curl.setopt(pycurl.WRITEDATA,f)
            self.curl.setopt(pycurl.NOPROGRESS,0)
            self.curl.setopt(pycurl.PROGRESSFUNCTION,self.progress)
            self.curl.perform()

        def resume(self):

            f = open(self.path,"ab")
            self.curl.setopt(pycurl.RESUME_FROM,os.path.getsize(self.path))
            self.curl.setopt(self.pycurl.WRITEDATA,f)
            self.curl.setopt(pycurl.NOPROGRESS,0)
            self.curl.setopt(pycurl.PROGRESSFUNCTION,self.progress)
            self.curl.perform()

Can anyone solve my problem or atleast give me a hint??
 

QwertyManiac

Commander in Chief
You're downloading within the application's thread. That would block it, naturally.

Try threading out your downloader operations as a solution, making it report some progress only when required. It would be a good exercise to add to your skill-building.
 

QwertyManiac

Commander in Chief
Yes, you should be able to use Python's own threads over QThreads. However, the latter supports the whole signals-and-slots concept, if you swing that way.
 

gk2k

gkbhat.blogspot.com
You should use threading. I do not know about Python threads, but QThread can do the job very well for you.
 
Top Bottom