2

I have a program running many threads, one of them controls the interface and another launches some functions every few seconds. I want the timing thread to update a progress bar but when I do, I get:

X Error: RenderBadGlyphSet (invalid GlyphSet parameter) 165
  Extension:    150 (RENDER)
  Minor opcode: 25 (RenderCompositeGlyphs32)
  Resource id:  0x25
X Error: RenderBadGlyphSet (invalid GlyphSet parameter) 165
  Extension:    150 (RENDER)
  Minor opcode: 25 (RenderCompositeGlyphs32)
  Resource id:  0x25
X Error: RenderBadGlyphSet (invalid GlyphSet parameter) 165
  Extension:    150 (RENDER)
  Minor opcode: 25 (RenderCompositeGlyphs32)
  Resource id:  0x25
X Error: RenderBadGlyphSet (invalid GlyphSet parameter) 165
  Extension:    150 (RENDER)
  Minor opcode: 25 (RenderCompositeGlyphs32)
  Resource id:  0x25
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread

Here is my code:

#!/usr/bin/python
from PyQt4 import QtCore, QtGui
import time

class WTrainning(wMeta.WMeta, QtGui.QWidget):

    def __init__(self):
        super(WTrainning, self).__init__()

    def createUI(self):
        
        ...
        self.progressBar = QtGui.QProgressBar(self)
        self.progressBar.setGeometry(QtCore.QRect(30, 70, 481, 23))
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName("progressBar")
        QtCore.QObject.connect(self.progressBar, QtCore.SIGNAL("valueChanged(int)"), self.progressBar.setValue) 
        ...

    def modifyBarr(self, number):
        self.progressBar.setValue(number)

class Crono(QtCore.QThread):
    
    def __init__(self, parent):
                
        QtCore.QThread.__init__(self,parent)


    def checkStatus(self):

        for x in range(1,101):
            self.wtobject.modifyBarr(x)                         
            time.sleep(1)
            

I'd tried with signals (new and old version) and making a dedicated thread for UI updating, but nothing worked. I'm using python 2.6.6 and pyqt 4.7.4

ThePyGuy
  • 17,779
  • 5
  • 18
  • 45
amusero
  • 33
  • 1
  • 1
  • 7
  • You're doing it wrong. You should definitely use signal and slot for this. – Kien Truong Mar 13 '12 at 10:45
  • You should indeed be using a signal and slot. Can you provide the code you tried with signals? – Chris Morgan Mar 13 '12 at 10:50
  • QtCore.QObject.connect(self.progressBar, QtCore.SIGNAL("valueChanged(int)"), self.progressBar.setValue) – amusero Mar 13 '12 at 10:58
  • Please update the question with signal/slot methods. But from what I see, you're connecting the wrong signals and slots of the wrong objects. – Kien Truong Mar 13 '12 at 11:09
  • Now is updated. I think the signal is correct because is the only signal available for progressBars in the reference guide. Probably the mistake is in the slot election. – amusero Mar 13 '12 at 11:22

1 Answers1

4

You have to define a signal for the Crono object like this:

class Crono(QtCore.QThread):
    tick = QtCore.pyqtSignal(int, name="changed") #New style signal

    def __init__(self, parent):
        QtCore.QThread.__init__(self,parent)

    def checkStatus(self):
        for x in range(1,101):
            self.tick.emit(x)                     
            time.sleep(1)

Then connect it to a slot of the progress bar.

class WTrainning(wMeta.WMeta, QtGui.QWidget):

    def __init__(self):
        super(WTrainning, self).__init__()
        self.crono = Crono()

    def createUI(self):
        #Create GUI stuff here

        #Connect signal of self.crono to a slot of self.progressBar
        self.crono.tick.connect(self.progressBar.setValue)

What you were doing is connect the SIGNAL valueChanged of the progressBar to its own SLOT setValue

Kien Truong
  • 11,179
  • 2
  • 30
  • 36