Hmm. 1st I've heard of daemonic. I'll give it a go tomorrow. Cheers
-Dave On Wed, Sep 16, 2009 at 2:52 PM, Chris G <[email protected]> wrote: > > Have you tried setting Thread.deamon / Thread.setDaemon() ? > If the thread is not daemonic, it may block python finalization. > > -Chris > > On Wed, Sep 16, 2009 at 6:25 AM, thirstydevil <[email protected]> > wrote: > > > > I've noticed a few issues using PyQt and pumpThread. It seems that > > randomly when users closes Maya it will do 1 of these: > > > > 1) Close successfully. > > 2) Not closes. Instead require 2 close requests by the user. > > 3) Closes but leaves 1 Maya thread running ( the pumpThread ) and > > still consuming Maya's memory footprint > > > > In an attempt to understand the problem I've reconfigured pumpThread > > based on Jon's and another user's version posted here (can't remember > > who and cant be bothered to hunt for it again, sorry to who ever you > > are). I'll blat out my thoughts and you guys can hopefully correct me > > or confirm my understanding. > > > > > ----------------------------------------------------------------------------------------------------------------------------------------------------------------- > > > > I've not done any multi threading stuff before, but this is what I > > understand is happening with pumpThread and the way in which it's > > operating. > > > > pumpThread is spawning 1 sub thread from Maya's main thread. The UI > > is executing in that new thread. > > threading.Thread( target = pumpQt, args = () ) > > > > Whenever a maya cmd is called in the PyQt UI code it is called with > > utils.executeDeferred( processor ) in pumpQt block. > > > > This intern is executed in maya's main thread when it can. I simply > > added the following line to the pumpQt whille loop print "pump..." > > makes sure a maya cmd is called every pumpThread cycle. > > > > As this loop is executing quicker than maya's main loop and stack of > > evalDeffered print statements build up in the main thread. In my > > pumpThread module I've created a global for the while loop (gPump). > > Using killPumpThread I can instantly stop and close the thread. But > > Maya is still printing "pump..." untill the stack of evalDeffered cmds > > have finished. > > > > Here's my test code with my new pumpThread module > > > > import pumpThread > > pumpThread.initializePumpThread() > > # Wait 20 secs > > pumpThread.killPumpThread() > > # only a small number of prints executed after thread is closed. Maybe > > 2-5 cycle depending > > > > # Load my PyQt UI and leave open and pumping for 20secs > > pumpThread.killPumpThread() > > # window closes quickly and tread die's in Task Manager. But 926 > > lines of pump... printed before maya is finished > > > > So how does that relate to the 3 errors above? > > > > 1) Close successfully. > > Thread has closed in time and Maya has no evaldeffers in the stack > > > > 2) Not closes. Instead require 2 close requests by the user. > > Thread has closed in time but maya is still pumping > > > > 3) Closes but leaves 1 Maya thread running ( the pumpThread ) and > > still consuming Maya's memory footprint > > Thread didn't close, UI could have been left open or maya not closing > > sun threads properly? > > > > It seems I can't do anything about error 2 as this is down to how > > much and often the threads are communicating. But I can help on error > > 3 by calling pumpThread.killPumpThread() with a script job on Maya > > exit. > > > > "RANT ON" > > I've spent nearly 6 months researching PyQt in Maya and so far > > (especially if you are having to support 64bit) I have to say it's > > allot of pain to maintain. Maya doesn't play nicely and will crash > > with no warning if you try to do something wrong or something it's not > > happy with. When you have 12 UI modules and 500 - 3000 lines of code > > in each it is a real headache to comment out blocks of code to find > > the line that is crashing Maya. Sometimes it's not you. I had one > > example where by I was creating a QIcon as a module global, it was > > being used allot in the UI. This line had been in for months, but all > > of a sudden was crashing Maya. I had to put the QIcon inside a class > > to solve the Maya crash. Developing a complex UI as I have with PyQT > > with lots of dependencies on Maya tools, like Pymel and clr means that > > you loose the ability to run the UI in Wings with debugging. > > Something you really need. Instead. I think using C++ Qt would give > > you the hooks to run in debug mode with Maya. You wouldn't have to > > compile 64bit PyQt as well. But then you loose the benefits of > > developing in a scripting environment. > > "RANT OFF" > > > > I'm sure that other studios trying to implement PyQT into there > > pipeline have faced these issues. I was wondering if anyone else > > could shed some light of the pit falls and hoops you are jumping > > through. > > > > Anyway here is my edited pumpThread module > > > > -Dave > > > ---------------------------------------------------------------------------------------------------------------------------------------------------------- > > > > from PyQt4 import QtCore, QtGui > > import maya.utils as utils > > import sys > > import time > > import threading > > import gc > > import maya.cmds as cmds > > > > pumpedThread = None > > app = None > > gPump = True > > > > def get_app(): > > global app > > return app > > > > def set_app(i_app): > > global app > > testAppInstance = QtCore.QCoreApplication.instance() > > if testAppInstance: > > app = testAppInstance > > else: > > app = i_app > > > > def get_pt(): > > global pumpedThread > > return pumpedThread > > > > def set_pt(i_pt): > > global pumpedThread > > pumpedThread = i_pt > > > > def pumpQt(): > > global app > > global gPump > > def processor(): > > app.processEvents() > > while gPump: > > time.sleep(0.01) > > utils.executeDeferred( processor ) > > #print "pump..." > > > > def killProcess(): > > global gPump > > gPump = False > > > > def killPumpThread(): > > if get_app(): > > get_app().closeAllWindows() > > if get_pt(): > > killProcess() > > set_pt(None) > > set_app(None) > > gc.collect() > > > > > > class QThreader(QtCore.QThread): > > '''An attempt to use QThread instead of Threading. Counld get > > this to pump in the same fasion''' > > def __init__(self, funcPointer, executeDeferred=True): > > super(QThreader, self).__init__() > > self.runThread = True > > self.funcPointer = funcPointer > > self.executeDeferred = executeDeferred > > > > def run(self): > > time = long(1) > > while self.runThread: > > self.usleep(time) > > if self.executeDeferred: > > utils.executeDeferred(self.funcPointer()) > > else: > > self.funcPointer() > > > > def killThread(self): > > self.runThread=False > > > > def startThread(self): > > self.runThread=True > > > > > > def initializePumpThread(): > > global gPump > > gPump = True > > if get_pt() == None: > > set_app(QtGui.QApplication(sys.argv)) > > set_pt(threading.Thread( target = pumpQt, args = () )) > > get_pt().start() > > > > > > > > > > > > > --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/python_inside_maya -~----------~----~----~----~------~----~------~--~---
