mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-12 09:17:50 -06:00
Make sure that project writer runs on Qt thread
CURA-5229 - Move @call_on_qt_thread to a separate module - Make sure that project writer runs on Qt thread because itself and the calls it makes can create new QObjects such as InstanceContainers, and this must happen on the Qt thread.
This commit is contained in:
parent
58e18ded18
commit
62521e93db
3 changed files with 38 additions and 33 deletions
34
cura/Utils/Threading.py
Normal file
34
cura/Utils/Threading.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
import threading
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
|
||||
|
||||
#
|
||||
# HACK:
|
||||
#
|
||||
# In project loading, when override the existing machine is selected, the stacks and containers that are correctly
|
||||
# active in the system will be overridden at runtime. Because the project loading is done in a different thread than
|
||||
# the Qt thread, something else can kick in the middle of the process. One of them is the rendering. It will access
|
||||
# the current stacks and container, which have not completely been updated yet, so Cura will crash in this case.
|
||||
#
|
||||
# This "@call_on_qt_thread" decorator makes sure that a function will always be called on the Qt thread (blocking).
|
||||
# It is applied to the read() function of project loading so it can be guaranteed that only after the project loading
|
||||
# process is completely done, everything else that needs to occupy the QT thread will be executed.
|
||||
#
|
||||
class InterCallObject:
|
||||
def __init__(self):
|
||||
self.finish_event = threading.Event()
|
||||
self.result = None
|
||||
|
||||
|
||||
def call_on_qt_thread(func):
|
||||
def _call_on_qt_thread_wrapper(*args, **kwargs):
|
||||
def _handle_call(ico, *args, **kwargs):
|
||||
ico.result = func(*args, **kwargs)
|
||||
ico.finish_event.set()
|
||||
inter_call_object = InterCallObject()
|
||||
new_args = tuple([inter_call_object] + list(args)[:])
|
||||
CuraApplication.getInstance().callLater(_handle_call, *new_args, **kwargs)
|
||||
inter_call_object.finish_event.wait()
|
||||
return inter_call_object.result
|
||||
return _call_on_qt_thread_wrapper
|
Loading…
Add table
Add a link
Reference in a new issue