Continued from How to use wxSpellCheckerDialog in Django?
I have added spell checking to Django application using pyenchant.
It works correctly when first run. But when I call it again (or after several runs) it gives following error.
PyAssertionError at /quiz/submit/
C++ assertion "wxThread::IsMain()"
failed at ....\src\msw\evtloop.cpp(244) in wxEventLoop::Dispatch():
only the main thread can process Windows messages
How to fix this?
You don't need wxPython to use pyEnchant. And you certainly shouldn't be using wx stuff with django. wxPython is for desktop GUIs, while django is a web app framework. As "uhz" pointed out, you can't call wxPython methods outside the main thread that wxPython runs in unless you use its threadsafe methods, such as wx.CallAfter. I don't know why you'd call wxPython from Django though.
It seems you are trying to use wx controls from inside Django code, is that correct? If so you are doing a very weird thing :)
When you write a GUI application with wxPython there is one main thread which can process Window messages - the main thread is defined as the one where wx.App was created. You are trying to do a UI thing from a non-UI thread. So probably at first run everything works (everything is performed in the GUI thread) but on second attempt a different python thread (spawned by django?) is performing some illegal GUI actions. You could try using wx.CallAfter which would execute a function from the argument in GUI thread but this is non-blocking. Also I've found something you might consider: wxAnyThread wxAnyThread. But I didn't use it and I don't know if it applies in your case.
Related
So I have a Tkinter application that I use at work. I wrote another Tkinter application that I wanted to call from the main Tkinter application. I know that Tkinter isn't 'thread safe', but I'm not 100% sure what that means. Does it mean that it can 'work', but it isn't guaranteed to work as written? Or should it just not work at all?
The reason I ask is because when I run the code below(self.thread_easy_imaging() is triggered by a filemenu option), it works just fine. So far I haven't encountered any issues and both GUIs are operational so far as I can tell. Is this because I'm using subprocess.call to call the script? I'm having a hard time wrapping my head around this because I know you can't use thread in a Tkinter app to do something like run a function while still being able to use buttons in the GUI, but for some reason when I use a thread to call the script with subprocess.call it does it just fine. When I wrote it, I assumed it wouldn't work, but for some odd reason it does. Here is an example of the code I'm using:
def thread_easy_imaging(self):
thread.start_new_thread(self.start_easy_imaging, ('EASY-IMAGING-1', 0))
def start_easy_imaging(self, thread_name, delay):
time.sleep(delay) #have to have args for some reason? I just did a delay of 0 seconds so I could use the tuple.
subprocess.call(['c:/python27/python.exe', 'EasyImaging.py'])
self.thread_easy_imaging()
I have only used this on a windows machine, but I'm guessing that it should work on any OS.
Edit: The scripts don't have to interact at all, I just want to add my other GUI application into the filemenu so I can call it as a separate application. If needed, I'll just use a Toplevel widget to recreate the application I want to call because it won't muck up the main thread at all.
Thanks in advance!
I've got the following problem:
I've written a script which is running up to four processes at the same time. Works like a charm when using it via command line.
Then I made the decision to write a GUI with wxPython and I was quickly figuring out that the GUI and the script need to run in different processes so both stay usable while the other is doing something. (i.e. being able to press a stop button while the script is running) This is also working perfectly.
Now the problem:
I just cannot communicate with the GUI while the script is running or at least I have no idea how. I'm trying to write output in a text window by passing "self" (the gui) to the script and in the script I try to do things like "self.outputWindow.WriteText('the script is doing bla 1 of bla 10')"
I even figured out why this won't work: self (the gui object) is not pickable and that's mandatory for multiprocessing, but I don't know how else I should do it.
You can use my tutorial on wxPython and threads, although I'm not sure if Python spreads those threads evenly to all the cores. I suspect it doesn't.
Fortunately, there are examples of using the multiprocessing module with wxPython. See the following links:
http://wiki.wxpython.org/MultiProcessing
wxPython non-blocking GUI threading AND multiprocessing?
wxpython GUI and multiprocessing - how to send data back from the long running process
http://www.blog.pythonlibrary.org/2012/08/03/python-concurrency-porting-from-a-queue-to-multiprocessing/
I hope those are helpful!
I've seen a lot of stuff about running code in subprocesses or threads, and using the multiprocessing and threading modules it's been really easy. However, doing this in a GUI adds an extra layer of complication.
From what I understand, the GUI classes don't like it if you try and manipulate them from multiple threads (or processes). The workaround is to send the data from whatever thread you created it in to the thread responsible for the graphics and then render it there.
Unfortunately, for the scenario I have in mind this is not an option: The gui I've created allows users to write their own plotting code which is then executed. This means I have no control over how they plot exactly, nor do I want to have it. (Update: these plots are displayed in separate windows and don't need to be embedded anywhere in the main GUI. What I want is for them to exist separated from the main GUI, without sharing any of the underlying stack of graphics libraries.)
So what I'm wondering now is
Is there some clean(ish) way of executing a string of python code in a whole new interpreter instance with its own ties to the windowing system?
In response to the comments:
The current application is set up as follows: A simple python script loads a wxPython gui (a wx.App). Using this gui users can set up a simulation, part of which involves creating a script in plain python that runs the simulation and post-processes the results (which usually involves making plots and displaying them). At the moment I'm doing this by simply calling exec() on the script code. This works fine, but the gui freezes while the simulation is running. I've experimented with running the embedded script in a subprocess, which also works fine, right up until you try to display the created graphs (usually using matplotlib's show()). At this point some library deep down in the stack of wxPython, wx, gtk etc starts complaining because you cannot manipulate it from multiple threads.
The set-up I would like to have is roughly the same, but instead of the embedded script sharing a GUI with the main application, I would like it to show graphics in an environment of its own.
And just to clarify:
This is not a question about "how do I do multithreading/multiprocessing" or even "how do I do multithreading/multiprocessing within a single wxpython gui". The question is how I can start a script from a gui that loads an entirely new gui. How do I get the window manager to see this script as an entirely separate application?
The easiest way would be to generate it in a temporary folder somewhere and then make a non-blocking call to the python interpreter, but this makes communication more difficult and it'd be quite hard to know when I could delete the temp files again. I was hoping there was a cleaner, dynamical way of doing this.
Can you simply use subprocess to run 'python.exe' and pipe the script in?
Alternatively, the multiprocessing package should suffice if you want to move some (pickle-able) data over to the new process in which you run the script. Just create a function/callable that runs the script, and create a Process object with the callable as target. That way, you should be able to pass some data over, without having GUI issues.
Capturing text with either is easy, subprocess allows that and no more. With multiprocess, you can pass python objects back and forth more easily.
On Windows, you can create window with a parent window from another process, and draw to that.
See the hWndParent argument to CreateWindowEx.
If wxWindows supports getting/setting that explicitly, then you should be good to go.
Depending on your platform, something similar might be possible in any windows system.
So, just giving your users the ability to find the handle of your apps window should give them the option to plot away at views embedded in your app, while running in their own processes.
I don't no much about wx, I work with jython(python implemented in java and you can use java) and swing. Swing has its own worker thread, and if you do gui updates you wrap your code into a runnable and invoke it with swing.invokelater.
You could see if wx has something like that, if you however are only allowed to manipulate the gui from the thread in which you created it try something similar. create a proxy object for your gui, which forwards all your calls to your thread which forwards them to the gui.
But proxying like this gets messy. how about you let them define classes, with an 'updateGui' function, that they should hand back to you over a queue and that you will execute in your gui thread.
In wxPython land when you use threads, you have to use its thread-safe methods to communicate with the GUI: wx.CallAfter, wx.CallLater or wx.PostEvent. In your case, I would run any long running code in a separate thread/process and when it's done its processing, send the result to the GUI. The GUI can instantiate a new frame and use matplotlib or PyPlot to show the plot, depending on which way you want to go. I've heard you can draw the plot using FloatCanvas too.
Anyway, if you instantiate the new frame correctly, then you can instantiate N frames and show them and be fine. See the wxPython wiki for a few examples of using Threads with wx: http://wiki.wxpython.org/LongRunningTasks
If I'm trying to create a window or prompt a file dialog in the IDLE shell, nothing opens and the shell restarts. Is this a bug of some kind? I can't find anything about it. I'm new to PyQt (and Python in general) but had been able to get tutorials to work correctly. The last day or so, if I open IDLE and import PyQt4, QtGui, etc and then run something simple like QFileDialog.getOpenFileName, the shell just restarts. Any ideas?
You need to have a QApplication before you can use anything else from PyQt. Try rereading some of the tutorials you followed, or do a few more. This one for example.
In the first code sample of the above tutorial, pay special attention to these lines (I've included the comments from the tutorial for convenience):
app = QtGui.QApplication(sys.argv)
Every PyQt4 application must create an application object. The
application object is located in the QtGui module. The sys.argv
parameter is a list of arguments from the command line. Python scripts
can be run from the shell. It is a way, how we can control the startup
of our scripts.
and
sys.exit(app.exec_())
Finally, we enter the mainloop of the application. The event handling
starts from this point. The mainloop receives events from the window
system and dispatches them to the application widgets. The mainloop
ends, if we call the exit() method or the main widget is destroyed.
The sys.exit() method ensures a clean exit. The environment will be
informed, how the application ended.
The exec_() method has an underscore. It is because the exec is a
Python keyword. And thus, exec_() was used instead.
It appears you might have forgotten about these. Or maybe you haven't realized that this means that you normally can't use PyQt with a running event loop in the interactive shell. However, there is a trick for that, see here.
I'm newbie in python and I'm trying to use pyinotify with a GUI interface using pygtk. I have two classes, my gtk class which doesn't do much, only displays stuff, and a class that handles the monitoring.
When I run them separately they do their work but when I try to load the gtk class from the other one, it only runs the gtk class, the monitor class only runs when I exit the GUI. If I comment the last line the monitor runs fine. I think the "myGTK.main" is blocking the whole process. Is there anything I can do?
pyinotify.ProcessEvent.__init__(self)
self.notifier = pyinotify.ThreadedNotifier(self.watch_manager, self)
self.watch_manager.add_watch('/test', pyinotify.IN_CREATE, rec=True)
self.notifier.start()
self.myGTK.main()
Thanks.
Per the comments, the solution appears to be to add
gobject.threads_init()
near the top of the script. This, and other useful information about using threads with pygtk can be found in this faq.