| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 4 | |
On 27.01.08 16:45:36, P. Mathé wrote: > I am sending you this message, originally sent to the PyQt mailing list, as it seems, according to Phil's answer that the problem lies within Qt. > As suggested by Phil, I changed the program to make the urllib call from within a different thread, but, if it partially solves the problem, it repaces one line of code by > more than fifty, makes the code almost unreadable, and disconnect the QListWidget from the QProgressBar updates. (the new code is at your disposal). > My point I that I just want that QListWidget works as expected , i.e. that when I say "addItem(...)", I see the item in the UI, now, not later , who knows when. Uhm, the QListWidget does have the item immediately, however the repainting only happens on the next run of the event loop. Calling QApplication::processEvents is known to break in certain situations, any longer-taking operation that shouldn't block the UI simply belongs into a separate thread or process. Its usage is specifically for those who know what they're doing. Most of the time you're far better off writing a short QThread subclass that does the "hard work" and sends either a custom event or simply a signal using Qt::QueuedConnection. Last but not least: If you want Qt behaviour to be changed, you need to write a bugreport to Trolltech. Andreas -- [ signature omitted ]
Le dimanche 27 janvier 2008, Andreas Pakulat a écrit : > On 27.01.08 16:45:36, P. Mathé wrote: > > I am sending you this message, originally sent to the PyQt mailing list, as it seems, according to Phil's answer that the problem lies within Qt. > > As suggested by Phil, I changed the program to make the urllib call from within a different thread, but, if it partially solves the problem, it repaces one line of code by > > more than fifty, makes the code almost unreadable, and disconnect the QListWidget from the QProgressBar updates. (the new code is at your disposal). > > My point I that I just want that QListWidget works as expected , i.e. that when I say "addItem(...)", I see the item in the UI, now, not later , who knows when. > > Uhm, the QListWidget does have the item immediately, however the > repainting only happens on the next run of the event loop. Calling > QApplication::processEvents is known to break in certain situations, any > longer-taking operation that shouldn't block the UI simply belongs into > a separate thread or process. Its usage is specifically for those who > know what they're doing. > > Most of the time you're far better off writing a short QThread subclass > that does the "hard work" and sends either a custom event or simply a > signal using Qt::QueuedConnection. I did it : the code is awfully ugly just to replace 1 line of code > > Last but not least: If you want Qt behaviour to be changed, you need to > write a bugreport to Trolltech. Thank you, I just did it > > Andreas > Pierre -- [ signature omitted ]
On 27.01.08 19:37:05, P. Mathé wrote: > Le dimanche 27 janvier 2008, Andreas Pakulat a écrit : > > On 27.01.08 16:45:36, P. Mathé wrote: > > > I am sending you this message, originally sent to the PyQt mailing list, as it seems, according to Phil's answer that the problem lies within Qt. > > > As suggested by Phil, I changed the program to make the urllib call from within a different thread, but, if it partially solves the problem, it repaces one line of code by > > > more than fifty, makes the code almost unreadable, and disconnect the QListWidget from the QProgressBar updates. (the new code is at your disposal). > > > My point I that I just want that QListWidget works as expected , i.e. that when I say "addItem(...)", I see the item in the UI, now, not later , who knows when. > > > > Uhm, the QListWidget does have the item immediately, however the > > repainting only happens on the next run of the event loop. Calling > > QApplication::processEvents is known to break in certain situations, any > > longer-taking operation that shouldn't block the UI simply belongs into > > a separate thread or process. Its usage is specifically for those who > > know what they're doing. > > > > Most of the time you're far better off writing a short QThread subclass > > that does the "hard work" and sends either a custom event or simply a > > signal using Qt::QueuedConnection. > > I did it : the code is awfully ugly just to replace 1 line of code 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 -- [ signature omitted ]
> 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... I'm not saying processEvents is the correct solution (see my other post) but a thread does seem a bit heavy for this particular problem as well... If the code was actually downloading the content of each URL... then I would put it in a thread.. but to simply iterate over a list of URLs and put each one in a tree should not require a thread Scott -- [ signature omitted ]
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. 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. Andreas -- [ signature omitted ]
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 > 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 > -- [ signature omitted ]
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. Andreas -- [ signature omitted ]
BTW... your issue is NOT a bug in QT... it's a bug in your understanding of how the model/view system works and refreshes the gui.. > -----Original Message----- > From: P. Mathé [mailto:pmathe@xxxxxxx] > Sent: Monday, January 28, 2008 3:49 AM > To: qt-interest@xxxxxxxxxxxxx; pyqt@xxxxxxxxxxxxxxxxxxxxxx > Subject: Re: [PyQt] processEvents on QlistWidget operations does nothing > > 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 > > 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 > > > > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ -- [ signature omitted ]
Le lundi 28 janvier 2008, Scott Aron Bloom a écrit : > BTW... your issue is NOT a bug in QT... it's a bug in your understanding of how the model/view system works and refreshes the gui.. You are right, it is a misunderstanding. Is is also a bug to understand that executing a QWidget.repaint() statement will immediately display the modified widget ? (I am referring to the doc that says : "Repaints the widget directly by calling paintEvent() immediately, unless updates are disabled or the widget is hidden." > > > -----Original Message----- > > From: P. Mathé [mailto:pmathe@xxxxxxx] > > Sent: Monday, January 28, 2008 3:49 AM > > To: qt-interest@xxxxxxxxxxxxx; pyqt@xxxxxxxxxxxxxxxxxxxxxx > > Subject: Re: [PyQt] processEvents on QlistWidget operations does nothing > > > > 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 > > > 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 > > > > > > > > > -- > > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with > > "unsubscribe" in the subject or the body. > > List archive and information: http://lists.trolltech.com/qt-interest/ > > -- > To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body. > List archive and information: http://lists.trolltech.com/qt-interest/ > > -- [ signature omitted ]
> Le lundi 28 janvier 2008, Scott Aron Bloom a écrit : > > BTW... your issue is NOT a bug in QT... it's a bug in your understanding > of how the model/view system works and refreshes the gui.. > You are right, it is a misunderstanding. > Is is also a bug to understand that executing a QWidget.repaint() > statement will immediately display the modified widget ? (I am referring > to the doc that says : > "Repaints the widget directly by calling paintEvent() immediately, unless > updates are disabled or the widget is hidden." > In my view... it should be followed with. The painting occurs on the next execution of the event loop... Scott -- [ signature omitted ]
On 28.01.08 12:40:36, Scott Aron Bloom wrote: > > Le lundi 28 janvier 2008, Scott Aron Bloom a écrit : > > > BTW... your issue is NOT a bug in QT... it's a bug in your understanding > > of how the model/view system works and refreshes the gui.. > > You are right, it is a misunderstanding. > > Is is also a bug to understand that executing a QWidget.repaint() > > statement will immediately display the modified widget ? (I am referring > > to the doc that says : > > "Repaints the widget directly by calling paintEvent() immediately, unless > > updates are disabled or the widget is hidden." > > > In my view... it should be followed with. The painting occurs on the next execution of the event loop... No it doesn't. The painting is done immediately, see src/gui/painting/qbackingstore.cpp. However I guess addItem does something that only happens in the next run of the event loop. Andreas -- [ signature omitted ]
Le lundi 28 janvier 2008, Andreas Pakulat a écrit :
> On 28.01.08 12:40:36, Scott Aron Bloom wrote:
> > > Le lundi 28 janvier 2008, Scott Aron Bloom a écrit :
> > > > BTW... your issue is NOT a bug in QT... it's a bug in your understanding
> > > of how the model/view system works and refreshes the gui..
> > > You are right, it is a misunderstanding.
> > > Is is also a bug to understand that executing a QWidget.repaint()
> > > statement will immediately display the modified widget ? (I am referring
> > > to the doc that says :
> > > "Repaints the widget directly by calling paintEvent() immediately, unless
> > > updates are disabled or the widget is hidden."
> > >
> > In my view... it should be followed with. The painting occurs on the next execution of the event loop...
>
> No it doesn't. The painting is done immediately, see
> src/gui/painting/qbackingstore.cpp.
>
> However I guess addItem does something that only happens in the next run
> of the event loop.
>
> Andreas
>
I must admit that I start to be lost. So to try to clarify the situation I have simplified my test :
I discarded the web access, no tmer, no threading. I kept only the updating of the progressBar : the loop is as follow :
def extraire(self):
jours=(1, 2, 3, 4)
self.progressBar.setValue(0)
self.progressBar.setMaximum(4)
for jour in jours:
time.sleep(1)
self.progressBar.setValue(self.progressBar.value() + 1)
#self.log.update()
#self.log.repaint()
#QCoreApplication.processEvents(QEventLoop.AllEvents)
print 'fini'
Seems to be straightforward, just for beginners ?
Now the tests :
Case1. As is with, the three lines commented out :
the progress bar is updated once : i.e 25% is displayed, then it jumps to 100% (probably 50%,75% and 100% displayed at once)
Case2. only "QCoreApplication.processEvents(QEventLoop.AllEvents)" uncommented :
the progress bar is updated normally : i.e 25%, 50%, 75% and 100% are displayed in turn.
Case3. only "self.log.repaint()" uncommented :
the progress bar is updated twice : i.e. 25% and 50% are displayed , then it jumps to 100% (probably 75% and 100% displayed at once)
Case4. only "self.log.update()" uncommented : same as Case 3.
Pierre
--
[ signature omitted ]
Thank you Mark for your suggestion, I will write a test program to check it.
Nevertheless, be aware that if I replace the "urllib.urlopen(next_url).read()" statement
by a 'time.sleep(2)" statement the behaviour is the same.
I will let you know the result of my test.
Pierre
Le lundi 28 janvier 2008, vous avez écrit :
> 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@xxxxxxxxxxxxxxxxxxxxxx
> > http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
>
>
--
[ signature omitted ]
> Thank you Mark for your suggestion, I will write a test program to check > it. > Nevertheless, be aware that if I replace the > "urllib.urlopen(next_url).read()" statement > by a 'time.sleep(2)" statement the behaviour is the same. > I will let you know the result of my test. > Pierre I would expect the behavior to be the same.. the code you wrote is functionally incorrect... The issue is not the download, or the sleep call... The blocking network call will just pause the update of the item till its done... But since your loop never lets the view compute and paint without a change not happening your not going to be successful. I have written pretty much the exact code your running (not in python but C++) and I can promise you... the problem is your code, not QTs and not Python... Look at the Model/View code base... then look how the QTreeWidget is implemented... While TT took away much of the responsibility of understanding the MV system with QTreeWidget, it is a MV system... Ok... SO rather then going on about this anylonger... :) Ive appended the code to do this... I use Sleep( 200 ) as a blocking delay... Note it was built on a Windows box... so you will need to remove #include <windows.h> and Sleep and replace it with the linux calls The code works, and will work with YOUR problem... I leave it to you to covert it to Python... Scott
Attachment:
Attachment:
main.cpp Attachment:
MyTreeWidget.h Attachment:
MyTreeWidget.cpp
Description: main.cpp
Description: MyTreeWidget.h
Description: MyTreeWidget.cpp
Message 15 in thread
Thank you, I recognize I was wrong.
Pierre
Le lundi 28 janvier 2008, Scott Aron Bloom a ÃcritÂ:
> > Thank you Mark for your suggestion, I will write a test program to
> check
> > it.
> > Nevertheless, be aware that if I replace the
> > "urllib.urlopen(next_url).read()" statement
> > by a 'time.sleep(2)" statement the behaviour is the same.
> > I will let you know the result of my test.
> > Pierre
>
>
> I would expect the behavior to be the same.. the code you wrote is
> functionally incorrect... The issue is not the download, or the sleep
> call...
>
>
> The blocking network call will just pause the update of the item till
> its done...
>
> But since your loop never lets the view compute and paint without a
> change not happening your not going to be successful.
>
> I have written pretty much the exact code your running (not in python
> but C++) and I can promise you... the problem is your code, not QTs and
> not Python...
>
> Look at the Model/View code base... then look how the QTreeWidget is
> implemented... While TT took away much of the responsibility of
> understanding the MV system with QTreeWidget, it is a MV system...
>
> Ok... SO rather then going on about this anylonger... :) Ive appended
> the code to do this... I use Sleep( 200 ) as a blocking delay...
>
> Note it was built on a Windows box... so you will need to remove
> #include <windows.h> and Sleep and replace it with the linux calls
>
> The code works, and will work with YOUR problem... I leave it to you to
> covert it to Python...
>
> Scott
>
--
[ signature omitted ]