[PyQt] First bottom-up GUI, acting strange

Nonyaz cheech at nonyaz.com
Sun Apr 19 04:58:16 BST 2009


I made an attempt to port over a little command line file DL script I
wrote into a GUI as a practice working with PyQt.
While I have seemingly achieved that goal, the resulting product is
not acting as I suspected. When I start a download,
the GUI will continue to update as long as I don't click it, as soon
as I do, the OS throws up "Not Responding" in the
title bar and the GUI no longer updates.  Even when I don't click it,
I can tell somethings not right, the start button never
releases, and the progress bar effects on vista are not apparent.

Hopefully someone can point out to me what I'm doing wrong, I have a
feeling its just bad event loop execution, although
I'm not quite sure how I could rewrite it so it wouldn't have this problem.

import urllib, os, time, sys, win32con
import win32clipboard as w
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Window(QDialog):
   def __init__(self, parent=None):
       super(Window, self).__init__(parent)

       self.lineedit = QLineEdit()
       self.getclip = QCommandLinkButton("Poll Clipboard")
       self.progbar = QProgressBar()
       self.speed = QLabel()
       self.status = QLabel()
       self.startb = QPushButton("Start DL")

       grid = QGridLayout()
       buttlay = QHBoxLayout()
       buttlay.addStretch()
       buttlay.addWidget(self.startb)
       grid.addWidget(self.lineedit,0,0)
       grid.addWidget(self.getclip,0,1)
       grid.addWidget(self.progbar,1,0,1,0)
       grid.addWidget(self.status,3,0)
       grid.addWidget(self.speed,3,1)
       grid.addLayout(buttlay,4,1)
       self.setLayout(grid)

       self.setWindowTitle("Clipboard DL V.001")
       self.lineedit.setText(getText())
       self.lineedit.setMinimumSize(300,0)
       self.startb.setMaximumSize(75,300)

       self.connect(self.startb, SIGNAL("clicked()"),
                    fileDL)
       self.connect(self.getclip, SIGNAL("clicked()"),
                    setClipText)


class myURLOpener(urllib.FancyURLopener):
   def http_error_206(self, url, fp, errcode, errmsg, headers, data=None):
       print "I've been 206'd!"
       pass

def getText():
   w.OpenClipboard()
   try:
       d = w.GetClipboardData(win32con.CF_TEXT)
   except:
       d = "None."
   w.CloseClipboard()
   if d[:7] != "http://":
       d = "Clipboard does not contain a valid URL."
   return d

def fileDL():
   loop = 1
   existSize = 0
   dlFile = getFilename()
   url = str(daprog.lineedit.text())

   myUrlclass = myURLOpener()
   webPage = myUrlclass.open(url)
   contentLength = int(webPage.headers['Content-Length'])

   if os.path.exists(str(dlFile)):
       outputFile = open(dlFile,"ab")
       existSize = os.path.getsize(dlFile)

       if existSize < contentLength:
           webPage.close()
           myUrlclass = None
           myUrlclass = myURLOpener()
           myUrlclass.addheader("Range","bytes=%s-" % (existSize))
           webPage = myUrlclass.open(url)

   else:
       try:
           outputFile = open(dlFile,"wb")
       except:
           os.mkdir(dldir+'/'+show)
       outputFile = open(dlFile,"wb")
       existSize = 0


   if existSize == contentLength:
       daprog.status.setText("All %s bytes already downloaded!\n" %
(contentLength))
       raw_input()
       loop = 0
   elif existSize == 0:
       pass
   elif existSize < contentLength:
       daprog.status.setText("Resuming download....")

   numBytes = existSize
   daprog.status.setText("Download Started")
   counterr = 0
   while loop:
       if counterr == 0:
           intime = time.time()
           daprog.progbar.setValue((float(numBytes)/float(contentLength)*100))
       data = webPage.read(8192)
       if not data:
           break
       outputFile.write(data)
       numBytes += len(data)
       if counterr == 10:
           counterr = -1
           outtime = time.time()
           lab = "%.2f KB/s" % (((8192*10)/(outtime-intime))/1000)
           daprog.speed.setText(lab)
       counterr += 1


   daprog.progbar.setValue(100)
   daprog.status.setText("Done")
   webPage.close()
   outputFile.close()



def getFilename():
   hack_fin = 0
   fname = ''
   for x in str(daprog.lineedit.text())[::-1]:
       if x == "/":
           hack_fin = 1
       if x != "/":
           if hack_fin == 0:
               fname += x
   return fname[::-1]

def setClipText():
   daprog.lineedit.setText(getText())


app = QApplication(sys.argv)
daprog = Window()
daprog.show()
daprog.exec_()


Thanks for your help,
- Adam


More information about the PyQt mailing list