[PyQt] processEvents on QlistWidget operations does nothing
apaku at gmx.de
Mon Jan 28 09:47:59 GMT 2008
On 28.01.08 09:48:35, 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).
> 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
Its not cpu-heavy, but its still something that takes a while to finish
(due to other constraints), so it shouldn't be done in code that blocks
the event loop.
> > 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.
Uhm, that takes simply a local QObject with a signal and a public
function with the same signature.
You can also live without all that and just queue your data in a class
that lives in the gui thread and use mutexes to handle concurrent
access. That won't need another qobject, just a QMutex and QMutexLocker
in 2 or 3 places in the code.
> Here is the modified program that works (I have changed p=urllib.urlopen(next_url).read() for time.sleep(2) for tests reasons).
Seems you forgot to attach it :)
> 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)
It does, it adds an item to the list widget. But this new items is
simply not drawn immediately because thats not how painting works in Qt,
its painted on the next run of the event loop. If you block running the
eventloop with your file-downloading then its quite natural that you
don't get an update until after the download is finished.
So this is it. We're going to die.
More information about the PyQt