[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    Re: [PyQt] QThread problem in linux
From:       mir amicitas <amicitas () gmail ! com>
Date:       2009-03-24 21:41:35
Message-ID: 55e194140903241441p2166ae7ck93ae63bccceff2a7 () mail ! gmail ! com
[Download RAW message or body]

(ack sorry I pressed the wrong button and sent it before it was done.
Here is the exciting conculsion . . .)

I think what you probably want to do here is to put your loadModule()
function in a thread instead of the the progress dialog.  That is to
say the program that you want to run in the background is in the
thread.

Then to communicate with the progress dialog, you can have
loadModule() emit events.
To have the dialog communicate with the thread (to cancel for example)
the simplest way is to give them both access to a variable that
defines the cancel state.  Then have your thread check this variable
occasionally.

The harder part is making sure that your thread can properly access
everything else that it needs in your application.  To do this you
will probably want to make use of a QMutexLocker in your thread.


I home some of this is helpful, I am not an expert on multithreaded
programming (though I have build a couple of applications).  Keeping
everything straight is kinda hard.

Novi


Here is a small example:

class LoadModuleThread(QThread):
   def __init__(self, moduleName):
       QThread.__init__(self)

       self.mutex = QtCore.QMutex()

   def run(self):
       with QtCore.QMutexLocker(self.mutex) as locker:
           t = og.Timer()

           for m in self.moduleList:
               if m.name == moduleName:
                   if m.hasDependencies: # load modules on wich the
main module depends before the main module is loaded
                       for moduleDependencie in m.moduleDependencies:
                           for m2 in self.moduleList:
                               if m2.name == moduleDependencie:

self.emit(QtCore.SIGNAL('setProgress'), 2, "Loading Dependencie: " +
moduleDependencie)
                                   m2.load()

               self.emit(QtCore.SIGNAL('setProgress'), 4, "Loading " +
moduleName)
               m.load()

           self.emit(QtCore.SIGNAL('loadingDone'))
           print "Time to load module: " + str(t.getMilliseconds() /
1000.0) + " seconds"


def startLoadingModules(self):
    self.thread = LoadModuleThread(moduleName)

    self.connect(self.thread
                        ,QtCore.SIGNAL('setProgress')
                        ,self.setProgress)
    self.connect(self.thread
                        ,QtCore.SIGNAL('loadingDone')
                        ,self.setProgressDone)

   self.progress = QProgressDialog("Loading " + moduleName, "Abort
Loading", min, max, None);
   self.progress.setWindowModality(Qt.WindowModal)
   self.progress.show()

   self.thread.start()

def setProgress(self, progress, labelText):
   self.progress.setLabelText(labelText)
   self.progress.setValue(progress)

def setProgressDone(self):
  self.progress.quit()


---------------
On Tue, Mar 24, 2009 at 11:38 AM, Stefan Stammberger
<sstammberger@web.de> wrote:
> 
> Hi,
> 
> I have a small QThread problem here. I'm trying to do a small progress bar in my \
> app while my app is working. I have already tried QApplication.processEvents() \
> which works very well in Windows but screws everything up in Linux. When I use it \
> my app receives key events only once in 10 tries, its completely unreliable. Now I \
> have read in a kde mailing list that QApplication.processEvents() is a bad thing \
> anyway I have tried putting the progress bar in its own thread. This is my \
> ProgreassBar class code: 
> class ProgressBarThread(QThread):
> def __init__(self, min, max, moduleName):
> QThread.__init__(self)
> self.progress = QProgressDialog("Loading " + moduleName, "Abort Loading", min, max, \
> None); self.progress.setWindowModality(Qt.WindowModal)
> 
> def setProgress(self, progress, labelText):
> self.progress.setLabelText(labelText)
> self.progress.setValue(progress)
> 
> def run(self):
> self.progress.show()
> self.exec_()
> 
> 
> And how I use it:
> 
> def loadModule(self, moduleName):
> t = og.Timer()
> 
> self.progress = ProgressBarThread(0, 8, moduleName)
> self.progress.start()
> 
> for m in self.moduleList:
> if m.name == moduleName:
> if m.hasDependencies: # load modules on wich the main module depends before the \
> main module is loaded for moduleDependencie in m.moduleDependencies:
> for m2 in self.moduleList:
> if m2.name == moduleDependencie:
> self.progress.setProgress(2, "Loading Dependencie: " + moduleDependencie)
> m2.load()
> self.modelSelectionDialog.scanDirForModels(m2.moduleRoot)
> self.materialSelectionDialog.scanDirForMaterials(m2.moduleRoot)
> self.mainModuledependencieList.append(m2)
> 
> self.progress.setProgress(4, "Loading " + moduleName)
> m.load()
> self.progress.setProgress(6, "Scan for models...")
> self.modelSelectionDialog.scanDirForModels(m.moduleRoot)
> self.progress.setProgress(8, "Scan for materials")
> self.materialSelectionDialog.scanDirForMaterials(m.moduleRoot)
> self.mainModule = m
> self.moduleExplorer.setCurrentModule(m)
> 
> self.progress.quit()
> print "Time to load module: " + str(t.getMilliseconds() / 1000.0) + " seconds"
> del t
> 
> When using this I get a few warnings:
> 
> QPixmap: It is not safe to use pixmaps outside the GUI thread
> QCoreApplication::sendPostedEvents: Cannot send posted events for objects in \
> another thread 
> And the worst:
> 
> X Error: RenderBadGlyphSet (invalid GlyphSet parameter) 181
> 
> Extension: 155 (RENDER)
> 
> Minor opcode: 25 (RenderCompositeGlyphs32)
> 
> Resource id: 0x0
> 
> 
> 
> When I get this error no text in my application is drawn at all. The strange thing \
> is, when I have a cleanly booted system, it works very well the first time I start \
> the application. On the second time I don't get any text. Two screen shots:
> How it looks without text: \
> http://picasaweb.google.de/some.fusion/Lockenwickler?feat=directlink#5316822651416543426
>  And how it should look: \
> http://picasaweb.google.de/some.fusion/Lockenwickler?feat=directlink#5316822694766353394
>  
> I don't know what I'm doing wrong here, I'm very new to the Threading stuff.
> 
> In case anybody wonders what my app is all about, its a game editor for an open \
> source game. http://www.youtube.com/watch?v=J-1ekVyv19o and \
> http://www.youtube.com/watch?v=R0ZKMbLtXYY 
> Sorry for this long email!
> 
> Thank you very much!
> Stefan Stammberger
> 
> 
> 
> 
> _______________________________________________
> PyQt mailing list    PyQt@riverbankcomputing.com
> http://www.riverbankcomputing.com/mailman/listinfo/pyqt

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic