[PyQt] First bottom-up GUI, acting strange

Geert Vancompernolle geert.discussions at gmail.com
Sun Apr 19 08:10:47 BST 2009


Nonyaz wrote:
> 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
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
>   
Could it be that you need a QApplication.processEvents() call in your 
"while" loop?  This command gives some CPU to the GUI to update itself.  
I'm afraid the "while" loop eats all CPU and there's no time/possibility 
to update the UI...

 From the documentation (QCoreApplication.processEvents()):

"
You can call this function occasionally when your program is busy 
performing a long operation (e.g. copying a file).
"

QApplication inherits QCoreApplication.

Just a thought...

-- 
Best rgds,

Geert
________________________________________________

*Use EcoCho <http://www.ecocho.com>: environmentally friendly search the 
internet!*


More information about the PyQt mailing list