[PyQt] processEvents on QlistWidget operations does nothing

Mark Summerfield mark at qtrac.eu
Mon Jan 28 09:25:09 GMT 2008


On 2008-01-28, P. Mathé wrote:
> Thank you guys for all the interest you have in my little problem (that in
> fact I consider as a Qt bug or design flaw).

I'm coming late to this thread, so please excuse me if I've
misunderstood, but I don't think the problem is a Qt bug or flaw.

I think the problem is that you are trying to mix a Python networking
library (urllib) with a GUI. The former blocks and the latter should not
be blocked.

One solution is to use PyQt's networking library instead since it does
not block. So the outline of a solution would be something like this:

    # start each download here
    def extraire(self):
	# ...
	for jour in jours:
	    ftp = QFtp(self) # or QHttp
	    # set up the network connection
	    ftplist.append(ftp) # ftplist = [] in __init__
	    self.connect(ftp,
		    SIGNAL("dataTransferProgress(qint64,qint64)"),
		    lambda: self.showProgress(ftp))
	    self.connect(ftp, SIGNAL("done(bool)"), self.handleDone)

    # show progress here
    def showProgress(self, ftp, done, total):
	# update the QProgressBar

    # do any "after downloading complete" processing here
    def handleDone(self, error):
	    
This is all untested pseudo-code. The point I'm making is that there are
two approaches to networking that I think work well with PyQt: (1) use
PyQt's networking classes and signals/slots to monitor progress, (2) use
a separate thread for networking as others have suggested. Oh, and I
guess there's a third approach: use Twisted---I believe that that
library has hooks so that it fits nicely into Qt's event loop.

>
> Le dimanche 27 janvier 2008, Andreas Pakulat a écrit :
> > On 27.01.08 13:36:37, Scott Aron Bloom wrote:
> > > > Its not about replacing 1 line of code, its about properly designing
> > > > your applications business logic. Moving heavy work into a thread is
> > >
> > > the
> > >
> > > > right thing to do (or separate process). QApplication::processEvents
> > >
> > > is
> > >
> > > > the ugly hack for those who are not able to use threads properly.
> > > >
> > > > Andreas
> > >
> > > But... adding 1 item to a list view.. is not heavy work.. And neigher
> > > does it appear that the creation of the complete list of items...
> >
> > Right, but thats not what the code actually does and I also suspect that
> > adding the item is still done in the main thread.
> >
> > > If the code was actually downloading the content of each URL... then I
> > > would put it in a thread..
> >
> > Thats exactly what the urllib-call (notice the read() at the end of that
> > line) does, it opens the url and reads the whole file.
>
> Yes I download an url page. But this is not what I call a heavy work, this
> is the opposite as the processor spend most of is time waiting for the web
> server to answer
>
> > And I suspect
> > that this is the part that got moved into a separate thread. Now maybe
> > I've just seen far worse code, but a short QThread::run() that iterates
> > over urls, downloads them and then emits a signal for each with whatever
> > content is needed doesn't look ugly to me.
>
> This is not so simple because the emit signal must be emitted from an
> object created in a non GUI thread context: it adds an indirection to the
> stuff. Here is the modified program that works (I have changed 
> p=urllib.urlopen(next_url).read() for  time.sleep(2) for tests reasons).
> Corrections to make it better designed are welcomed, but I am still
> convinced that the original one was better. (remember that I do not want
> the QApplication.processEvents in it : QListWidget.addItem should work
> normally without it)
>
> > Andreas
>
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt



-- 
Mark Summerfield, Qtrac Ltd., www.qtrac.eu




More information about the PyQt mailing list