Re: [PyQt] QPainter::end: Painter ended with 2 saved states

2011-07-01 Thread Hans-Peter Jansen
Hi Eric,

sorry for the delay.

On Tuesday 28 June 2011, 21:42:51 Eric Frederich wrote:
> Here is a reworked example.
> Do you see any potential problems with this one?
> Is the call to setText okay?

Sure, it's done from the main thread, hence in the main thread context.

> Is it okay to access the data member the way I'm doing it in
> print_data?

Hmm, you access Blah.data after your 'SLEPT' loop finished. In this 
special case, it seems save, but it reminded me on one of 
Linus' "special" phrases: "Yes, it's manly, but let's face it, so is 
bungee-jumping with the cord tied to your testicles."

Okay, might be a bit exaggerated for this case..

Anyway, you should turn your code to use new style signals/slots. Raises 
readability and greatly reduces strokes. BTW, I tend to use lambda 
expressions instead of partials, but that's more of a personal 
preference. 

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


Re: [PyQt] QPainter::end: Painter ended with 2 saved states

2011-06-28 Thread Eric Frederich
Here is a reworked example.
Do you see any potential problems with this one?
Is the call to setText okay?
Is it okay to access the data member the way I'm doing it in print_data?

Thanks,
~Eric

from PyQt4.QtCore import *
from PyQt4.QtGui  import *

class Blah(QThread):
def __init__(self, parent=None):
super(Blah, self).__init__(parent)
self.data = []

def run(self):
import time
for i in xrange(10):
time.sleep(.1)
txt = '%02d' % i
self.emit(SIGNAL('SLEPT'), txt)
self.data.append(txt)
self.emit(SIGNAL("ALLDONE"))

from functools import partial

class MyDialog(QDialog):

def __init__(self, *args, **kwargs):
super(MyDialog, self).__init__(*args, **kwargs)
self.setWindowTitle("Hey, hows it going?")

layout = QVBoxLayout()
for i in xrange(15):
button = QPushButton("Push Me", self)
self.connect(button, SIGNAL("pressed()"), self.do_something)
layout.addWidget(button)

self.setLayout(layout)

def do_something(self):
self.sender().setEnabled(False)
b = Blah(self)
self.connect(b, SIGNAL('ALLDONE'),
partial(self.sender().setText, "Push Me"))
self.connect(b, SIGNAL('ALLDONE'), partial(self.print_data, b))
self.connect(b, SIGNAL('ALLDONE'),
partial(self.sender().setEnabled, True))
self.connect(b, SIGNAL('SLEPT'), self.sender().setText)
b.start()

def print_data(self, blah):
print blah.data

if __name__ == '__main__':
import sys
app = QApplication(sys.argv[1:])
md = MyDialog()
md.show()
sys.exit(app.exec_())



On Tue, Jun 28, 2011 at 3:05 PM, Hans-Peter Jansen  wrote:
> On Tuesday 28 June 2011, 20:52:12 Eric Frederich wrote:
>> I was trying to get an example working with a QThread.
>> I wound up creating one but after running it for a while and pressing
>> buttons I got the error...
>> QPainter::end: Painter ended with 2 saved states
>>
>> Am I doing something wrong?
>> I wanted an example where a worker thread would query a database or
>> some other long running operation and leave the GUI responsive
>> (although disabling certain elements like the button it was launched
>> from).
>>
>> This is the code I was running
>>
>> from PyQt4.QtCore import *
>> from PyQt4.QtGui  import *
>>
>> class Blah(QThread):
>>     def __init__(self, parent=None):
>>         super(Blah, self).__init__(parent)
>>         print 'new thread created'
>>
>>     def run(self):
>>         print 'running'
>>         self.parent().setEnabled(False)
>>         import time
>>         for i in xrange(10):
>>             self.parent().setText("%02d" % i)
>>             time.sleep(.1)
>>         self.parent().setText("Push Me")
>>         self.parent().setEnabled(True)
>
> You're doing "bad" things here, that you shouldn't do from a thread,
> e.g. using methods, that trigger redraws. You should create signals in
> your thread, that signals operations to the main thread, where you
> would actually process these operations without fear.
>
> Pete
>
> ___
> PyQt mailing list    PyQt@riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt
>
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] QPainter::end: Painter ended with 2 saved states

2011-06-28 Thread Hans-Peter Jansen
On Tuesday 28 June 2011, 20:52:12 Eric Frederich wrote:
> I was trying to get an example working with a QThread.
> I wound up creating one but after running it for a while and pressing
> buttons I got the error...
> QPainter::end: Painter ended with 2 saved states
>
> Am I doing something wrong?
> I wanted an example where a worker thread would query a database or
> some other long running operation and leave the GUI responsive
> (although disabling certain elements like the button it was launched
> from).
>
> This is the code I was running
>
> from PyQt4.QtCore import *
> from PyQt4.QtGui  import *
>
> class Blah(QThread):
> def __init__(self, parent=None):
> super(Blah, self).__init__(parent)
> print 'new thread created'
>
> def run(self):
> print 'running'
> self.parent().setEnabled(False)
> import time
> for i in xrange(10):
> self.parent().setText("%02d" % i)
> time.sleep(.1)
> self.parent().setText("Push Me")
> self.parent().setEnabled(True)

You're doing "bad" things here, that you shouldn't do from a thread, 
e.g. using methods, that trigger redraws. You should create signals in 
your thread, that signals operations to the main thread, where you 
would actually process these operations without fear.

Pete

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


[PyQt] QPainter::end: Painter ended with 2 saved states

2011-06-28 Thread Eric Frederich
I was trying to get an example working with a QThread.
I wound up creating one but after running it for a while and pressing
buttons I got the error...
QPainter::end: Painter ended with 2 saved states

Am I doing something wrong?
I wanted an example where a worker thread would query a database or
some other long running operation and leave the GUI responsive
(although disabling certain elements like the button it was launched
from).

This is the code I was running

from PyQt4.QtCore import *
from PyQt4.QtGui  import *

class Blah(QThread):
def __init__(self, parent=None):
super(Blah, self).__init__(parent)
print 'new thread created'

def run(self):
print 'running'
self.parent().setEnabled(False)
import time
for i in xrange(10):
self.parent().setText("%02d" % i)
time.sleep(.1)
self.parent().setText("Push Me")
self.parent().setEnabled(True)

def say_hi():
print 'HELLO'

class MyDialog(QDialog):
def __init__(self, *args, **kwargs):
super(MyDialog, self).__init__(*args, **kwargs)
self.setWindowTitle("Hey, hows it going?")
layout = QHBoxLayout()

self.buttons = []
for i in xrange(5):
button = QPushButton("Push Me")
self.buttons.append(button)
blah = Blah(button)
self.connect(button, SIGNAL("pressed()"), blah.start)
layout.addWidget(button)

self.setLayout(layout)

if __name__ == '__main__':
import sys
app = QApplication(sys.argv[1:])
md = MyDialog()
md.show()
sys.exit(app.exec_())
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt