Many (if not most) GUI applications run into problems if you try to update/redraw the UI from another thread. Just imagine what would happen if you had one thread trying to write "blue" 100x to a file, and another thread trying to write "red" 100x. You'll see something like:
redblueredblruede...
(granted with Python you have the GIL so you might not get precisely that same effect, but using multiprocessing you could probably make it happen).
The exact same thing would happen to your graphical application if one thread is trying to turn a region blue, while the other is trying to turn it red. Because that's undesirable, there are guards put in place to stop it from happening by throwing exceptions like the one you encountered.
What you have happening here is something like this:
----(UI Thread)-,----------------->
`---(new thread)-----(affect the UI)-X kaboom!
What you want to have happen is something like this:
----(UI Thread)-,--------------------------------------,---(affect the UI)-->
/
`---(new thread)-----(pass result)-`
The exact mechanics of it will change from framework to framework. In .NET you've got an if (thing.InvokeRequired){ thing.BeginInvoke(data); }
On Windows, COM objects are protected the same sort of way. If you create an COM object on a thread it doesn't like you trying to access it on a different thread. So if you're creating it on a different thread and you still need to interact with it you're going to have to communicate across your threads.
If your code isn't blocking, or it doesn't take very long to run (i.e. < 250ms) then running the calls on the main thread should be just fine. Typically UI frameworks allow you to register a callback to be executed after N
amount of time, and then it will just be executed on the main thread whenever it can be.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…