Open danielstockton opened 12 years ago
I'll have a look at that later today.
My change is not the solution. I still receive the error, albeit less frequently.
A better solution, for me at least, is just to instantiate a singleton Ghost object when my application starts up and use that throughout.
What's the status on this issue? I've the same problem
In my case was solved by opening a new subprocess, creating the Ghost instance there and then exiting it when finished.
I have this same problem in a WSGI application. I am getting this error: QObject: Cannot create children for a parent that is in a different thread. (Parent is QNetworkAccessManager(0x7f8114c62380), parent's thread is QThread(0x7f81142c2090), current thread is QThread(0x7f81200c5d30)
A quick google showed me this post http://stackoverflow.com/a/3268185/867162, which seems to concern the same problem, which involves multi threading. But how to solve problem, I don't know.
I have been digging into the problem and am a bit wiser. The QNetworkAccessManager (in self.manager in Ghost) is the culprit. It seems QNetworkAccessManager is only started once, when Ghost is instantiated, even when you instantiate Ghost again, the same QNetworkAccessManager is used. So if you have a multithreaded application which instantiates Ghost() each time, the QNetworkAccessManager seems to be shared between these threads, which it doesn't like. But also if you start Ghost() only once, and each thread calls it's open() method, still you run into problems because the open() call can be run from different threads than the thread where Ghost() was instantiated, causing access to self.manager from the wrong thread again. So the point where you call Ghost() and Ghost.open() does not seem to make any difference.
Ok, I now have a solution. By launching Ghost in a separate process, using multiprocessing, and thus effectively bypassing the GIL, you avoid the threading issues, since Ghost, QNetworkAccessManager and everything else Ghost/QT related is started in (one and the same) separate process.
This is what I did:
def createScreenshot(url,filename,features,layername):
ghost=Ghost(viewport_size=(900,900),log_level=logging.DEBUG)
ghost.open(url,method='post',body=urllib.urlencode({'features':features,'layername':layername}))
ghost.capture_to(filename,region=(0,0,800,800))
class SomeClass(object):
def some_method(self):
.......
proc=multiprocessing.Process(target=createScreenshot,args=(url,filename,features,layername))
proc.start()
proc.join()
I am having the same issue, however the solution with multiprocessing does not work, I receive the following error when using multiprocessing:
QWaitCondition: Destroyed while threads are still waiting
The following code in the view is enough to cause the problem:
It seems to exit more cleanly with the following change, at least I no longer receive any errors:
https://github.com/danielstockton/Ghost.py/blob/master/ghost/ghost.py#L330