Re: [PyQt] Processing signals from a called method while the method executes

2010-07-02 Thread Andreas Pakulat
On 01.07.10 21:35:44, alan moore wrote:
 I've encountered this problem twice now in subtle ways, I think this
 is at the root of my last question about the QWebView; I've included
 sample code this time to illustrate.
 
 In the attached script, I have a widget class and a processor class.
 The processor represents some kind of processing engine that's going
 to do a lengthy multi-part routine of some kind.  The widget class
 is the gui for the engine.
 
 The go button is connected to the process method of the
 processor object.  The process() method emits a signal with a
 string, does process A for 10 seconds, emits a signal with a string,
 does process B for 10 seconds, and emits a final signal with a
 string.
 
 The widget class is supposed to be picking up the signals and
 displaying the strings. So the expected output is:
 
 click go
 first message displays
 wait 10 seconds
 second message displays
 wait 10 seconds
 final message displays
 
 The actual output is that nothing happens for 20 seconds, then all
 the text displays.  Because the widget isn't going to process any
 received signals until the called method exits.
 
 How do I produce the expected behavior here?

Don't block the event-loop with your processor. The signals are
delivered as you expect, but the widget is not redrawn with that
message. The reason is that your processing blocks the Qt event loop and
hence no painting is done.

Possible options to not block the event loop that long would be to use a
QTimer to schedule each part of your processing after the next
event-loop run. The other option would be moving the processing into a
separate thread, you should only go this route after making familiar
with multi-threading though.

Andreas

-- 
Break into jail and claim police brutality.
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] multiple inheritance and MappedType

2010-07-02 Thread Phil Thompson
On Thu, 1 Jul 2010 15:51:48 -0600, Clinton Stimpson cjstimp...@gmail.com
wrote:
 Hi,
 
 I've got an existing library with python wrappers generated with a
 different 
 tool, and I've successfully used MappedType to interface with that and
I'm 
 getting the interoperability I'm looking for.
 
 But now I want to use sip to wrap a class that derives from two classes,
 one 
 is QObject, and the other is a MappedType.
 
 I'm getting an error from sip:
 A class, exception, namespace or mapped type has already been defined
with
 the 
 same name
 
 Is inheritance from a MappedType not supported?

Correct.

An alternative approach is to invent a new class (as far as SIP is
concerned) which you can sub-class from.

For example, in Qt QItemSelection is sub-classed from
QListQItemSelectionRange (which would be implemented as a MappedType). 
In PyQt QItemSelection isn't sub-classed from anything but has the useful
methods from QList added.

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


Re: [PyQt] SIP Bug: virtual function wrapped twice due to deep inheritance from base class and ABC

2010-07-02 Thread Phil Thompson
On Thu, 1 Jul 2010 17:53:23 -0700 (PDT), Demetrius Cassidy
dcassid...@mass.rr.com wrote:
 Phil,
 
 It's not code specific to that class. It's due to the deep inheritance
 tree.
 You should be able to run my test code and get the same results.
 
 Basically to sum it up:
 
 PTCPSocket  - PIPDataGramSocket - PIPSocket - PSocket (ABC)
 
 PTCPSocket, PIPSocket and PSocket all define a virtual function called
 'Listen'.
 Commenting 'Listen' out from PSocket, and SIP does not include the
function
 twice.
 Listen is NOT a pure virtual function in the ABC, it has a body.
 Listen is fully defined in PTCPSocket, and the other classes except
 PIPDataGramSocket.

The error appears in PUDPSocket but you don't even mention that class.
Where does it fit in the inheritance tree?

Phil


 Phil Thompson-5 wrote:
 
 On Sat, 19 Jun 2010 10:27:55 -0700 (PDT), Demetrius Cassidy
 dcassid...@mass.rr.com wrote:
 Basically I have a Listen() function in a derived class, that is also
in
 the 
 base and ABC. For some reason sip ends up wrapping the same function
 twice
 (it 
 has a body in the ABC), even though it's a virtual function in all of
 the
 
 derived classes. If I comment out this function in the ABC, everything
 works 
 fine, but otherwise I get a C2535 compiler error with Visual C++. 
  
 Here is what sip comes up with: 
  
 class sipPUDPSocket : public PUDPSocket 
 { 
  
 /* 
  * There is a protected method for every virtual method visible
from

  * this class. 
  */ 
  protected: 
 PBoolean Listen(unsigned,WORD,PIPSocket::Reusability); 
 /*more wrapped functions*/ 
 PBoolean Listen(unsigned,WORD,PIPSocket::Reusability); // --
 duplicate
 function 
 }; 
  
 C++ nmake errors: 
  
 sippyptlibPTCPSocket.cpp 
 .\sippyptlibPTCPSocket.cpp(121) : error C2535: 'PBoolean 
 sipPTCPSocket::Listen(unsigned int,WORD,PSocket::Reusability)' 
 : member function already defined or declared 
 .\sippyptlibPTCPSocket.cpp(102) : see declaration of 
 'sipPTCPSocket::Listen' 
  
  
 .\sippyptlibPTCPSocket.cpp(506) : error C2084: function 'PBoolean
 sipPTCPSocket: 
 :Listen(unsigned int,WORD,PSocket::Reusability)' already has a body 
 .\sippyptlibPTCPSocket.cpp(102) : see previous definition of
 'Listen' 
  
  
 Basic code structure based on what I am wrapping - note that I only
 included
 the 
 offending function here, as it would be too much code to include
 everything. 
 
 But you at least need to include the definition of PUDPSocket.
 
 typedef bool PBoolean; 
  
 class PTCPSocket : PIPDataGramSocket 
 { 
  public: 
   virtual PBoolean Listen(unsigned int, WORD, PSocket::Reusability); 
 } 
  
 class PIPDataGramSocket : PIPSocket 
 { 
   protected: 
 PIPDataGramSocket(); 
 } 
  
 class PIPSocket : PSocket 
 { 
  public: 
   virtual PBoolean Listen(unsigned int, WORD, PSocket::Reusability); 
 } 
  
 class PSocket /Abstract/ 
 { 
   public: 
 /// Flags to reuse of port numbers in Listen() function. 
 enum Reusability { 
   CanReuseAddress, 
   AddressIsExclusive 
 }; 
  
   virtual PBoolean Listen(unsigned int, WORD, PSocket::Reusability); //

 commenting this function out fixes this problem 
  
  protected: 
 /*This function calls os_socket() with the correct parameters for
 the
 
socket protocol type. 
  */ 
 virtual PBoolean OpenSocket() = 0; 
  
 }; 
 
 Phil
 ___
 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] Synchronous WebView.load()

2010-07-02 Thread Phil Thompson
On Fri, 02 Jul 2010 00:31:40 -0500, alan moore m...@alandmoore.com wrote:
 As I understand it, the webview doesn't actually load the page and
update
 itself until the method call returns; at which point it loads the new
 page and
 updates the history.

No, the load starts straight away but may not finish until some time later
(probably after the method returns).

The view will update itself when it has enough of the page loaded to be
usefully displayed.

The display won't actually change until the even loop runs.

 To illustrate the problem I'm having a little more clearly, I've 
 attached a sample script.  The script is supposed to conduct a brief 
 tour of a list of websites when you hit the go button on the browser 
 toolbar.  Each site shows for five seconds, then the next on loads.
 
 Only that's not what happens.  If you run it, you'll see that hitting 
 go causes the browser to hang for about 20 seconds, then the final 
 comment is all that shows.  In other words, for the whole duration of 
 the method call, the main window is asleep.
 
 I guess this is just another instance of the trouble I was running into 
 on my other program, which I posted a demonstration script for earlier 
 today.  I would really appreciate any help on this matter.

You need to get rid of your loop and sleep() and connect to the
QWebView.loadFinished() signal. In the connected slot start a timer for 5
seconds. When that timer times out you can then set the next URL.

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


Re: [PyQt] Processing signals from a called method while the method executes

2010-07-02 Thread alanm
On Friday 02 July 2010 1:17:06 am Andreas Pakulat wrote:
 
 Don't block the event-loop with your processor. The signals are
 delivered as you expect, but the widget is not redrawn with that
 message. The reason is that your processing blocks the Qt event loop and
 hence no painting is done.
 
 Possible options to not block the event loop that long would be to use a
 QTimer to schedule each part of your processing after the next
 event-loop run. The other option would be moving the processing into a
 separate thread, you should only go this route after making familiar
 with multi-threading though.
 
 Andreas

Thanks for the reply.  I don't think I understand, though.  I read in the 
QTimer documentation where I can do a zero-millisecond timer to schedule 
things after the next event run, but changing

sleep(10)

To:

QTimer.singleShot(0, lambda: sleep(10))

Seemed like it should do that.  It doesn't.  Apparently the 
processor.process() method is still blocking.   Where am I going wrong here?
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Synchronous WebView.load()

2010-07-02 Thread alanm
On Friday 02 July 2010 3:04:40 am you wrote:
 On Fri, 02 Jul 2010 00:31:40 -0500, alan moore m...@alandmoore.com wrote:
  As I understand it, the webview doesn't actually load the page and
 
 update
 
  itself until the method call returns; at which point it loads the new
  page and
  updates the history.
 
 No, the load starts straight away but may not finish until some time later
 (probably after the method returns).
 
 The view will update itself when it has enough of the page loaded to be
 usefully displayed.
 
 The display won't actually change until the even loop runs.
 

Thanks for the response.  From my experimenting with this, apparently the 
history doesn't update until after the display does.  I tried something like 
this:

def reset_browser(self):
self.webview.load(self.homepage)
while self.webview.history().currentItem().url() != self.homepage:
pass
self.webview.history().clear()

With the idea being that I'd wait until the history had changed to clear it, 
but it never changed.  The while loop went on infinitely.

  To illustrate the problem I'm having a little more clearly, I've
  attached a sample script.  The script is supposed to conduct a brief
  tour of a list of websites when you hit the go button on the browser
  toolbar.  Each site shows for five seconds, then the next on loads.
  
  Only that's not what happens.  If you run it, you'll see that hitting
  go causes the browser to hang for about 20 seconds, then the final
  comment is all that shows.  In other words, for the whole duration of
  the method call, the main window is asleep.
  
  I guess this is just another instance of the trouble I was running into
  on my other program, which I posted a demonstration script for earlier
  today.  I would really appreciate any help on this matter.
 
 You need to get rid of your loop and sleep() and connect to the
 QWebView.loadFinished() signal. In the connected slot start a timer for 5
 seconds. When that timer times out you can then set the next URL.
 
 Phil

I can see how that works for this example.  In the case of my original 
program, I'm not so sure.  I can't connect webview.history().clear() to 
loadFinished(), or else every single page load will clear the history.  And I 
can't connect and disconnect in the same callback, because it won't be 
processed until the callback exits.

Thanks again for your help.
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] SIP Bug: virtual function wrapped twice due to deep inheritance from base class and ABC

2010-07-02 Thread Demetrius Cassidy

Sorry Phil - corrected inheritance tree:

PUDPSocket - PIPDataGramSocket - PIPSocket - PSocket (ABC) 
PTCPSocket - PIPSocket - PSocket (ABC)

PUDPSocket does not have a 'Listen' function in it, instead it just inherits
it from PIPSocket, who overrides PSocket. 

PTCPSocket DOES include a 'Listen' function in it, and overrides it from
PIPSocket and PSocket.

I've attached the corresponding sip files and the generated .cpp files from
sip. 

Below I've also included a snippet of the generated code for both classes.
The weird thing is that SIP wraps the PIPSocket Listen function, along with
the one from PSocket. http://old.nabble.com/file/p29056623/ptlib.rar
ptlib.rar 


class sipPUDPSocket : public PUDPSocket
{
public:


/*
 * There is a protected method for every virtual method visible from
 * this class.
 */
protected:
...
PBoolean Listen(unsigned,WORD,PIPSocket::Reusability);
PBoolean Listen(const
PIPSocket::Address,unsigned,WORD,PIPSocket::Reusability);
...
PBoolean Listen(unsigned,WORD,PSocket::Reusability);
}

class sipPTCPSocket : public PTCPSocket
{
public:
...
/*
 * There is a protected method for every virtual method visible from
 * this class.
 */
protected:
PBoolean Listen(unsigned,WORD,PIPSocket::Reusability);
PBoolean Listen(const
PIPSocket::Address,unsigned,WORD,PIPSocket::Reusability);
...
PBoolean Listen(unsigned,WORD,PSocket::Reusability);
};

Both classes share the same exact inheritance bug when wrapped:

Phil Thompson-5 wrote:
 
 On Thu, 1 Jul 2010 17:53:23 -0700 (PDT), Demetrius Cassidy
 dcassid...@mass.rr.com wrote:
 Phil,
 
 It's not code specific to that class. It's due to the deep inheritance
 tree.
 You should be able to run my test code and get the same results.
 
 Basically to sum it up:
 
 PTCPSocket  - PIPDataGramSocket - PIPSocket - PSocket (ABC)
 
 PTCPSocket, PIPSocket and PSocket all define a virtual function called
 'Listen'.
 Commenting 'Listen' out from PSocket, and SIP does not include the
 function
 twice.
 Listen is NOT a pure virtual function in the ABC, it has a body.
 Listen is fully defined in PTCPSocket, and the other classes except
 PIPDataGramSocket.
 
 The error appears in PUDPSocket but you don't even mention that class.
 Where does it fit in the inheritance tree?
 
 Phil
 
 
 Phil Thompson-5 wrote:
 
 On Sat, 19 Jun 2010 10:27:55 -0700 (PDT), Demetrius Cassidy
 dcassid...@mass.rr.com wrote:
 Basically I have a Listen() function in a derived class, that is also
 in
 the 
 base and ABC. For some reason sip ends up wrapping the same function
 twice
 (it 
 has a body in the ABC), even though it's a virtual function in all of
 the
 
 derived classes. If I comment out this function in the ABC, everything
 works 
 fine, but otherwise I get a C2535 compiler error with Visual C++. 
  
 Here is what sip comes up with: 
  
 class sipPUDPSocket : public PUDPSocket 
 { 
  
 /* 
  * There is a protected method for every virtual method visible
 from

  * this class. 
  */ 
  protected: 
 PBoolean Listen(unsigned,WORD,PIPSocket::Reusability); 
 /*more wrapped functions*/ 
 PBoolean Listen(unsigned,WORD,PIPSocket::Reusability); // --
 duplicate
 function 
 }; 
  
 C++ nmake errors: 
  
 sippyptlibPTCPSocket.cpp 
 .\sippyptlibPTCPSocket.cpp(121) : error C2535: 'PBoolean 
 sipPTCPSocket::Listen(unsigned int,WORD,PSocket::Reusability)' 
 : member function already defined or declared 
 .\sippyptlibPTCPSocket.cpp(102) : see declaration of 
 'sipPTCPSocket::Listen' 
  
  
 .\sippyptlibPTCPSocket.cpp(506) : error C2084: function 'PBoolean
 sipPTCPSocket: 
 :Listen(unsigned int,WORD,PSocket::Reusability)' already has a body 
 .\sippyptlibPTCPSocket.cpp(102) : see previous definition of
 'Listen' 
  
  
 Basic code structure based on what I am wrapping - note that I only
 included
 the 
 offending function here, as it would be too much code to include
 everything. 
 
 But you at least need to include the definition of PUDPSocket.
 
 typedef bool PBoolean; 
  
 class PTCPSocket : PIPDataGramSocket 
 { 
  public: 
   virtual PBoolean Listen(unsigned int, WORD, PSocket::Reusability); 
 } 
  
 class PIPDataGramSocket : PIPSocket 
 { 
   protected: 
 PIPDataGramSocket(); 
 } 
  
 class PIPSocket : PSocket 
 { 
  public: 
   virtual PBoolean Listen(unsigned int, WORD, PSocket::Reusability); 
 } 
  
 class PSocket /Abstract/ 
 { 
   public: 
 /// Flags to reuse of port numbers in Listen() function. 
 enum Reusability { 
   CanReuseAddress, 
   AddressIsExclusive 
 }; 
  
   virtual PBoolean Listen(unsigned int, WORD, PSocket::Reusability); //
 
 commenting this function out fixes this problem 
  
  protected: 
 /*This function calls os_socket() with the correct parameters for
 the
 
socket protocol type. 
  */ 
 virtual PBoolean OpenSocket() = 0; 
  
 }; 
 
 Phil
 ___
 PyQt 

Re: [PyQt] Processing signals from a called method while the method executes

2010-07-02 Thread Jan Haag
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 7/2/10 3:38 PM, alanm wrote:
 On Friday 02 July 2010 1:17:06 am Andreas Pakulat wrote:

 Don't block the event-loop with your processor. The signals are
 delivered as you expect, but the widget is not redrawn with that
 message. The reason is that your processing blocks the Qt event loop and
 hence no painting is done.

 Possible options to not block the event loop that long would be to use a
 QTimer to schedule each part of your processing after the next
 event-loop run. The other option would be moving the processing into a
 separate thread, you should only go this route after making familiar
 with multi-threading though.

 Andreas
 
 Thanks for the reply.  I don't think I understand, though.  I read in the 
 QTimer documentation where I can do a zero-millisecond timer to schedule 
 things after the next event run, but changing
 
 sleep(10)
 
 To:
 
 QTimer.singleShot(0, lambda: sleep(10))
 
 Seemed like it should do that.  It doesn't.  Apparently the 
 processor.process() method is still blocking.   Where am I going wrong here?

What this actually does is to start a single-shot QTimer (timing out
immediately) to run a callback during the next run of the event-loop;
Thus far, you understood things correctly. However, _INSIDE_ this
callback, you still set the GUI-thread and, as a consequence, the
event-loop to sleep for 10 seconds. This is obviously not what you
wanted... A better idea would be to call

QTimer.singleShot(1, your_actual_processing_callback)

which delivers a timeout event triggering your callback after 10 seconds
(1 ms).
The difference is that a QTimer runs asynchronously in a thread by
itself, while sleep runs synchronously in the thread it is called in,
thus blocking the event loop which does the same.

The processing callback should be reasonably short-running, otherwise
you'll run into the same problem again; in this case, your best bet is
to work your way into multithreading using the QThread class and
triggering your processing-thread's run method as the timer callback.
However, threads are often a good way to mess things up completely
(deadlocks etc...), so don't go for them unless you really have to.

Jan
-BEGIN PGP SIGNATURE-
Version: GnuPG/MacGPG2 v2.0.14 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJMLhvdAAoJEJY4GpQWZadM80EP/iEhiNdKICnezSYwaknTs/Fv
GyV9J6LDi+jfj8wf9yMfFxoUp0Qwlu+ncAPMq5MIZG95HPepKEzPn9JY7dA9WfsP
+Ehkyb5LiutL3lZCWvHoujFK4zv4XQJJt+llPCOTEjgw93EM2X9UNYcIeTucN6J/
LMSJIldfgBBLzr4NNal3nPEutfM7QTs6FqZ08+P9bBs/cOqf0Y5UbWmwhBxUAPnv
zOus/DmQ7GVZcpdoyvjdtmA2JAHJJ8DyJeJC7deOHFVA+E+2Lfu4Uvl+QHZzKGKa
fQEySvtG6QvITyNloJvpYozfAM8Rv/Wwb5sIOc8u2cLmUZ0K7UvrN/NK6Y+yhfe+
/NVGKSpoTHeW21ib4q5rK2/tGZ9iCvJRtfmLLGUDWvLlm/OW1Jro2kowXeZAJmmH
MVLOMofQOs8ZlefgVwGn2CavMTHDH/lSnLQ/thpQgE0s4Y0M5lANn1TTPM+n5GWf
eIIaqc1tzJQI9cdwL6rhbdP3R8Q9EMKMPjupWhC5gEy8SAIMWv1vRD6qVym57ov/
TBoYlEUgx0K1xJMFcCKCwsfI2sUNzL/BYKMf5eG54ij/KxPDhS3Kg6y2IGXglm9r
e/ZPIgqBjhbFMxznYui3o2rATPOUU5T7ChP9ONq+R4PCCNWV6L1u/sErqe2c/Fid
jpN5/NBrXHrPzAeFxuEv
=Cowg
-END PGP SIGNATURE-


0x1665A74C.asc
Description: application/pgp-keys


0x1665A74C.asc.sig
Description: Binary data
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Re: [PyQt] Processing signals from a called method while the method executes

2010-07-02 Thread alanm
On Friday 02 July 2010 12:03:29 pm Jan Haag wrote:
 On 7/2/10 3:38 PM, alanm wrote:
  On Friday 02 July 2010 1:17:06 am Andreas Pakulat wrote:
  Don't block the event-loop with your processor. The signals are
  delivered as you expect, but the widget is not redrawn with that
  message. The reason is that your processing blocks the Qt event loop and
  hence no painting is done.
  
  Possible options to not block the event loop that long would be to use a
  QTimer to schedule each part of your processing after the next
  event-loop run. The other option would be moving the processing into a
  separate thread, you should only go this route after making familiar
  with multi-threading though.
  
  Andreas
  
  Thanks for the reply.  I don't think I understand, though.  I read in the
  QTimer documentation where I can do a zero-millisecond timer to schedule
  things after the next event run, but changing
  
  sleep(10)
  
  To:
  
  QTimer.singleShot(0, lambda: sleep(10))
  
  Seemed like it should do that.  It doesn't.  Apparently the
  processor.process() method is still blocking.   Where am I going wrong
  here?
 
 What this actually does is to start a single-shot QTimer (timing out
 immediately) to run a callback during the next run of the event-loop;
 Thus far, you understood things correctly. However, _INSIDE_ this
 callback, you still set the GUI-thread and, as a consequence, the
 event-loop to sleep for 10 seconds. This is obviously not what you
 wanted... A better idea would be to call
 
 QTimer.singleShot(1, your_actual_processing_callback)
 
 which delivers a timeout event triggering your callback after 10 seconds
 (1 ms).
 The difference is that a QTimer runs asynchronously in a thread by
 itself, while sleep runs synchronously in the thread it is called in,
 thus blocking the event loop which does the same.

I think I confused everyone with the sleep(10) calls; the intention wasn't to 
actually have a ten second delay, but just to have a place-holder for some 
real call that might take 10 seconds or more, such as a file copy, subprocess 
call, etc.

Anyway, I finally solved my problem using threads; by making processor 
subclass QThread instead of QObject, renaming process() to run() and 
connecting the gobutton to processor.start() I got the correct behavior.

Thanks for your response.
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt