Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread Frédéric

Le 19/1/2009, Giovanni Bajo ra...@develer.com a écrit:

This would work on Qt4 as well, but of course it's not ideal as you need 
a timer to poll the queue. It's much easier to use QThreads and simply 
post the events (or use the asynchronous signals).

Plus, you can now do non-trivial things from the secondary threads (eg: 
painting with QPainter over a QImage) so it's worth sitting down and 
analyzing all these possibilities before desiging the code with Qt4.

I started to use QThreads, and I have some minor problems.

When my app was build on PyGTK, I was using standard python threads, and
a serializer to push PyGTK calls from the threads. The serializer queue
was periodically read and executed from the main thread.

I replaced the python threads by QThread, and removed all serializer
calls. This works pretty well (and faster), except for one thing: I
can't refresh my progressbar from the thread. Doing this output the
following message:

QPixmap: It is not safe to use pixmaps outside the GUI thread
QPainter: It is not safe to use drawPixmap() outside the GUI thread

The documentation says that a QPainter can only paint on QImage, QPrinter
and QPicture, but not on QWidget and QPixmap (it seems that painting on
QGraphicsItem works fine, as I don't have warnings; can you confirm?).

So, how can I refresh my progressbar from my thread? Is there a Qt
mecanism I could use? I'm not that familiar with Qt custom
events/signals or so...

Thanks,

--
   Frédéric

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread dboddie
On Tue Feb 3 10:28:26 GMT 2009, Giovanni Bajo wrote:

 The trick is that a signal/slot connection across a thread is different
 from a normal one: in a normal connection, slots are called immediately,
 within the emit() call. Instead, in an asynchronous connection, when
 the signal is emitted, an event is posted to the main thread (posting
 events is thread-safe); then the receiving thread's exec loop will
 process the event and call the correct slot.

For those that don't already know about it, there's an example of inter-
thread signal-slot communication in the PyQt Wiki:

  http://www.diotavelli.net/PyQtWiki/Threading,_Signals_and_Slots

The Mandelbrot example included with PyQt4 also shows this technique.

David
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread Frédéric

Le 3/2/2009, Giovanni Bajo ra...@develer.com a écrit:

 PS: does it already exist a simple solution to adapt this code:
 
 thread = threading.Thread(target=func)
 thread.start()
 
 using QThread?

Yes: QtConcurrent::run.

:o)

Thank you all for your help!

--
   Frédéric

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread Frédéric

Le 3/2/2009, Giovanni Bajo ra...@develer.com a écrit:

The trick is that a signal/slot connection across a thread is different
from a normal one: in a normal connection, slots are called immediately,
within the emit() call. Instead, in an asynchronous connection, when
the signal is emitted, an event is posted to the main thread (posting
events is thread-safe); then the receiving thread's exec loop will
process the event and call the correct slot.

In this last case, does the call to emit() immediatly return, and the
thread go on with the next instruction, or does it wait until the event
has really called the slot?

--
   Frédéric

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread Albert Cervera i Areny
A Dimarts 03 Febrer 2009, Frédéric va escriure:
 PS: does it already exist a simple solution to adapt this code:

 thread = threading.Thread(target=func)
 thread.start()

 using QThread?

Not that I know of, but it's trivial to implement. Something like this should 
do:

class FunctionThread(QThread):
def __init__(self, function, parent=None):
QThread.__init__(self, parent)
self.function = function

def run(self):
self.function()


 --
Frédéric

 ___
 PyQt mailing listPyQt@riverbankcomputing.com
 http://www.riverbankcomputing.com/mailman/listinfo/pyqt



-- 
Albert Cervera i Areny
http://www.NaN-tic.com
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread Frédéric
On mardi 03 février 2009, Giovanni Bajo wrote:

  In this last case, does the call to emit() immediatly return, and the
  thread go on with the next instruction, or does it wait until the
  event has really called the slot?

 Depends on the connection type (which you can manually specify during
 the connect() call, or leave the default).

 The default (for connections between different threads) is
 Qt.QueuedConnection, which means that the emit() call exits immediately.
 Otherwise, you can specify Qt.BlockingQueueConnection: the emitting
 thread will wait until the receiving thread has found time to process
 all the slots.

Ok (Qt is really powerfull!). 

 Notice that it's easy to deadlock, if you don't pay enough attention (and
 even if you do ;).

Why do you say it is easy to deadlock? Do you mean that Qt can do 
unexpected things?

-- 
Frédéric

http://www.gbiloba.org

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread Giovanni Bajo

On 2/3/2009 5:17 PM, Frédéric wrote:

On mardi 03 février 2009, Giovanni Bajo wrote:
Notice that it's easy to deadlock, if you don't pay enough attention (and

even if you do ;).


Why do you say it is easy to deadlock? Do you mean that Qt can do 
unexpected things?


No: I meant that a programmer's mistake is easy because you're basically 
blocking a thread on another one. If for instance you send a similar 
blocking queued signal from this thread to the former, you get a 
deadlock (since the former is blocked waiting for the first signal to 
finish its process).


My suggestion mostly is not to use blocking queue signals.
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-02-03 Thread Giovanni Bajo

On 2/3/2009 12:24 PM, Frédéric wrote:

Le 3/2/2009, Giovanni Bajo ra...@develer.com a écrit:


The documentation says that a QPainter can only paint on QImage, QPrinter
and QPicture, but not on QWidget and QPixmap (it seems that painting on
QGraphicsItem works fine, as I don't have warnings; can you confirm?).

I'm unsure but yes, it probably works because it's a simply a QImage
under the hoods.


Ok.


Read the documentation about connecting signals and slots across threads
(asynchronous thread connection). What you want is to simply emit a
signal from the thread (self.emit(SIGNAL(UPDATED_PROGRESS), value)),
and connect to that signal from the main thread; in the slot, update the
widget.

The trick is that a signal/slot connection across a thread is different
from a normal one: in a normal connection, slots are called immediately,
within the emit() call. Instead, in an asynchronous connection, when
the signal is emitted, an event is posted to the main thread (posting
events is thread-safe); then the receiving thread's exec loop will
process the event and call the correct slot.


Ok, I got it! I'll try to implement this...

Thanks again for your help :o)

PS: does it already exist a simple solution to adapt this code:

thread = threading.Thread(target=func)
thread.start()

using QThread?


Yes: QtConcurrent::run.
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-20 Thread Giovanni Bajo
On mar, 2009-01-20 at 12:08 +0800, Christoph Burgmer wrote:
 Am Tuesday, 20. January 2009 schrieb Giovanni Bajo:
 
  On 1/19/2009 4:36 PM, Christoph Burgmer wrote:
 
 [...]
 
   I am doing a
 
  
 
   QCoreApplication.postEvent()
 
  
 
   out of run() from a threading.Thread class without any
 problems.
 
 
 
  That's only because you are lucky. It's not something that's
 officially
 
  supported and I have spent days debugging random crashes that turned
 out
 
  being Qt accesses from threads allocated by Python.
 
 
 
  I suggest you to fix your code.
 
 We have an unlucky situation here, Qt documents neither say that
 mixing threading libraries is ok, nor does it say it could lead to
 clashes.

To be more precise, using a different underlying C-level library is not
going to fly. The question here is: assuming that Python and Qt ends up
calling the same underlying library (eg: pthread on Linux), does it work
if I create a thread from Python and then use Qt's calls?

 Now guessing won't help, but I'll do it anyway:
 
 QCoreApplication::postEvent() is thread-safe and thus has the
 highest safety level one could whish for in the Qt threading system.
 It works by adding the event to the event queue and returning
 immediatelly.
 
 It's the main event loop that then takes over.
 
 Now from that I would assume the only clashes could occur when
 fiddeling with the event queue. Instead of assuming some magic done in
 every thread I rather believe that synchronisation is done in the
 local method, postEvent(). Now things going wrong would mean that
 synchronisation there does depend on the threads all adhering to the
 same special protocol, something that IMHO is not needed to complete
 this task.

For your reasoning to be true, QThread's constructor should be an empty
function. Instead QThread's constructor initializes a QThreadPrivate
object, whose create a QThreadData TLS object, who is in turn vital to
the working of, eg., QThread::current(), that postEvent() calls.

Moreover, it's not only postEvent() at stake here: you are probably
constructing an event object before passing it to postEvent(), so you
will have to check that everything also in there is compatible with
using a different high-level threading library (included, eg., object
construction and ownership transfer at both the sip/pyqt/qt level).
-- 
Giovanni Bajo
Develer S.r.l.
http://www.develer.com


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Christoph Burgmer
Am Monday, 19. January 2009 schrieb Giovanni Bajo:
 On 1/19/2009 3:13 PM, eliben wrote:
  I've seen various references to this issue before, but nothing to fully
  address it as I'd expect.
 
  Can you comment on the pros and cons of using QThread vs Python's threads
  with PyQt?
 
  I'll begin: on the surface, Python's threads make more sense because
  they're Qt independent and can be ported between apps that don't
  necessarily depend on Qt (for example a web version of a GUI app). The
  Python thread API is powerful enough for all uses, it seems.
 
  However, there are concerns. Perhaps QThreads are more efficient? Or
  maybe more tightly integrated with the other parts of PyQt, so it's
  easier to use them?

 It's mostly the same. The main difference is that QThreads are better
 integrated with Qt (asynchrnous signals/slots, event loop, etc.). Also,
 you can't use Qt from a Python thread (you can't for instance post event
 to the main thread through QApplication.postEvent): you need a QThread
 for that to work.

I am doing a
QCoreApplication.postEvent()
out of run() from a threading.Thread class without any problems.

Christoph
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Frédéric

Le 19/1/2009, Christoph Burgmer chri...@gmx.de a écrit:

I am doing a
QCoreApplication.postEvent()
out of run() from a threading.Thread class without any problems.

Under which plateform?

--
   Frédéric

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Sergio Jovani
Hi,

I always used QThread and emit() in order to communicate with main
QThread without problems:

thread = Thread(self)
self.connet(thread, SIGNAL(Signal))
thread.start()

2009/1/19 Christoph Burgmer chri...@gmx.de:
 Am Monday, 19. January 2009 schrieb Giovanni Bajo:

 On 1/19/2009 3:13 PM, eliben wrote:

  I've seen various references to this issue before, but nothing to fully

  address it as I'd expect.

 

  Can you comment on the pros and cons of using QThread vs Python's
  threads

  with PyQt?

 

  I'll begin: on the surface, Python's threads make more sense because

  they're Qt independent and can be ported between apps that don't

  necessarily depend on Qt (for example a web version of a GUI app). The

  Python thread API is powerful enough for all uses, it seems.

 

  However, there are concerns. Perhaps QThreads are more efficient? Or

  maybe more tightly integrated with the other parts of PyQt, so it's

  easier to use them?



 It's mostly the same. The main difference is that QThreads are better

 integrated with Qt (asynchrnous signals/slots, event loop, etc.). Also,

 you can't use Qt from a Python thread (you can't for instance post event

 to the main thread through QApplication.postEvent): you need a QThread

 for that to work.

 I am doing a

 QCoreApplication.postEvent()

 out of run() from a threading.Thread class without any problems.

 Christoph

 ___
 PyQt mailing listPyQt@riverbankcomputing.com
 http://www.riverbankcomputing.com/mailman/listinfo/pyqt

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Sergio Jovani
Sorry!


thread = Thread(self)
self.connet(thread, SIGNAL(Signal), self.Slot)
thread.start()

2009/1/19 Sergio Jovani lese...@gmail.com:
 Hi,

 I always used QThread and emit() in order to communicate with main
 QThread without problems:

 thread = Thread(self)
 self.connet(thread, SIGNAL(Signal))
 thread.start()

 2009/1/19 Christoph Burgmer chri...@gmx.de:
 Am Monday, 19. January 2009 schrieb Giovanni Bajo:

 On 1/19/2009 3:13 PM, eliben wrote:

  I've seen various references to this issue before, but nothing to fully

  address it as I'd expect.

 

  Can you comment on the pros and cons of using QThread vs Python's
  threads

  with PyQt?

 

  I'll begin: on the surface, Python's threads make more sense because

  they're Qt independent and can be ported between apps that don't

  necessarily depend on Qt (for example a web version of a GUI app). The

  Python thread API is powerful enough for all uses, it seems.

 

  However, there are concerns. Perhaps QThreads are more efficient? Or

  maybe more tightly integrated with the other parts of PyQt, so it's

  easier to use them?



 It's mostly the same. The main difference is that QThreads are better

 integrated with Qt (asynchrnous signals/slots, event loop, etc.). Also,

 you can't use Qt from a Python thread (you can't for instance post event

 to the main thread through QApplication.postEvent): you need a QThread

 for that to work.

 I am doing a

 QCoreApplication.postEvent()

 out of run() from a threading.Thread class without any problems.

 Christoph

 ___
 PyQt mailing listPyQt@riverbankcomputing.com
 http://www.riverbankcomputing.com/mailman/listinfo/pyqt


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Christoph Burgmer
Am Monday, 19. January 2009 schrieben Sie:
 Le 19/1/2009, Christoph Burgmer chri...@gmx.de a écrit:
 I am doing a
 QCoreApplication.postEvent()
 out of run() from a threading.Thread class without any problems.

 Under which plateform?

Linux.

I initially made a short check if their was any argument against using Python 
threads with Qt and then dediced for the Python ones as:
- learning Python threading helps you more in overall Python programming
- documentation is at hand in the usual documentation style.

Giovanni's response strikes me as it would be a serious annoyance if I had to 
change my threading model only to port my application to Windows and Mac. I 
don't even get any QPainter or other thread related warnings in my app, 
something which KDE throws out on a per minute basis.

Christoph
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Frédéric
On lundi 19 janvier 2009, Christoph Burgmer wrote:

  QCoreApplication.postEvent()
  out of run() from a threading.Thread class without any problems.
 
  Under which plateform?

 Linux.

 I initially made a short check if their was any argument against using
 Python threads with Qt and then dediced for the Python ones as:
 - learning Python threading helps you more in overall Python programming
 - documentation is at hand in the usual documentation style.

 Giovanni's response strikes me as it would be a serious annoyance if I
 had to change my threading model only to port my application to Windows
 and Mac. I don't even get any QPainter or other thread related warnings
 in my app, something which KDE throws out on a per minute basis.

Strange you don't get any issues... As X11 is not thread-safe, you should 
get some X11 errors, leading to crashs.

I use python threads, but I have a serializer to push all Qt calls on a 
queue, and this queue is processed from the main thread, using a QTimer 
timeout signal.

But all this is true for Qt3, and things may have changed in Qt4...

-- 
Frédéric

http://www.gbiloba.org

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Giovanni Bajo

On 1/19/2009 4:36 PM, Christoph Burgmer wrote:

Am Monday, 19. January 2009 schrieb Giovanni Bajo:

  On 1/19/2009 3:13 PM, eliben wrote:

   I've seen various references to this issue before, but nothing to fully

   address it as I'd expect.

  

   Can you comment on the pros and cons of using QThread vs Python's 
threads


   with PyQt?

  

   I'll begin: on the surface, Python's threads make more sense because

   they're Qt independent and can be ported between apps that don't

   necessarily depend on Qt (for example a web version of a GUI app). The

   Python thread API is powerful enough for all uses, it seems.

  

   However, there are concerns. Perhaps QThreads are more efficient? Or

   maybe more tightly integrated with the other parts of PyQt, so it's

   easier to use them?

 

  It's mostly the same. The main difference is that QThreads are better

  integrated with Qt (asynchrnous signals/slots, event loop, etc.). Also,

  you can't use Qt from a Python thread (you can't for instance post event

  to the main thread through QApplication.postEvent): you need a QThread

  for that to work.

I am doing a

QCoreApplication.postEvent()

out of run() from a threading.Thread class without any problems.


That's only because you are lucky. It's not something that's officially 
supported and I have spent days debugging random crashes that turned out 
being Qt accesses from threads allocated by Python.


I suggest you to fix your code.
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Giovanni Bajo

On 1/19/2009 5:03 PM, Christoph Burgmer wrote:

Giovanni's response strikes me as it would be a serious annoyance if I 
had to change my threading model only to port my application to Windows 
and Mac. I don't even get any QPainter or other thread related warnings 
in my app, something which KDE throws out on a per minute basis.


You don't get any warning because nobody suggested Trolltech to add 
warning to detect the usage of an external threading library with Qt. 
With C++, you can see that it makes absolutely no sense to bring an 
external threading library instead of using Qt, so it's not a common error.

--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Giovanni Bajo

On 1/19/2009 5:37 PM, Frédéric wrote:

I use python threads, but I have a serializer to push all Qt calls on a 
queue, and this queue is processed from the main thread, using a QTimer 
timeout signal.


This would work on Qt4 as well, but of course it's not ideal as you need 
a timer to poll the queue. It's much easier to use QThreads and simply 
post the events (or use the asynchronous signals).


Plus, you can now do non-trivial things from the secondary threads (eg: 
painting with QPainter over a QImage) so it's worth sitting down and 
analyzing all these possibilities before desiging the code with Qt4.


This is the correct link to get a broad overview:
http://doc.trolltech.com/4.4/threads.html
--
Giovanni Bajo
Develer S.r.l.
http://www.develer.com


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Frédéric
On lundi 19 janvier 2009, Giovanni Bajo wrote:

 On 1/19/2009 5:37 PM, Frédéric wrote:
  I use python threads, but I have a serializer to push all Qt calls on
  a queue, and this queue is processed from the main thread, using a
  QTimer timeout signal.

 This would work on Qt4 as well, but of course it's not ideal as you need
 a timer to poll the queue. It's much easier to use QThreads and simply
 post the events (or use the asynchronous signals).

 Plus, you can now do non-trivial things from the secondary threads (eg:
 painting with QPainter over a QImage) so it's worth sitting down and
 analyzing all these possibilities before desiging the code with Qt4.

 This is the correct link to get a broad overview:
 http://doc.trolltech.com/4.4/threads.html

You convinced me ;o)

As I plan to use the MVC-delegate pattern provided in Qt, I will need to 
have some Qt-dependent code in my model, so, better use all Qt features...

-- 
Frédéric

http://www.gbiloba.org

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Threads with PyQt. Qt's or Python's?

2009-01-19 Thread Christoph Burgmer
Am Tuesday, 20. January 2009 schrieb Giovanni Bajo:
 On 1/19/2009 4:36 PM, Christoph Burgmer wrote:
[...]
  I am doing a
 
  QCoreApplication.postEvent()
 
  out of run() from a threading.Thread class without any problems.

 That's only because you are lucky. It's not something that's officially
 supported and I have spent days debugging random crashes that turned out
 being Qt accesses from threads allocated by Python.

 I suggest you to fix your code.

We have an unlucky situation here, Qt documents neither say that mixing 
threading libraries is ok, nor does it say it could lead to clashes.

Now guessing won't help, but I'll do it anyway:
QCoreApplication::postEvent() is thread-safe and thus has the highest safety 
level one could whish for in the Qt threading system. It works by adding the 
event to the event queue and returning immediatelly.
It's the main event loop that then takes over.

Now from that I would assume the only clashes could occur when fiddeling with 
the event queue. Instead of assuming some magic done in every thread I rather 
believe that synchronisation is done in the local method, postEvent(). Now 
things going wrong would mean that synchronisation there does depend on the 
threads all adhering to the same special protocol, something that IMHO is not 
needed to complete this task.

Anyway, if somebody should have a bit more indepth knowledge on that, please 
step up.

Christoph
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt