Last active
February 3, 2023 02:46
-
-
Save theodox/2f0bd8a4d9b189bc0ab02bef2d6a80cf to your computer and use it in GitHub Desktop.
Delegates UnrealEd draw ticks to a PySide2 Application, allowing non-blocking updates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
""" | |
import unreal | |
import PySide2.QtWidgets as widgets | |
import traceback | |
class UEQApplication (widgets.QApplication): | |
""" | |
Ensure that an application never tries to `exec_` inside of Unreal | |
""" | |
def exec_(self, *args): | |
pass | |
# patch QApplication to make sure exec_ is not available | |
widgets._QApplication = widgets.QApplication | |
widgets.QApplication = UEQApplication | |
APP = UEQApplication() | |
APP.setApplicationName("UE4 Python") | |
APP.setApplicationDisplayName("UE4 Python") | |
# how many uncaught exceptions can bubble up before we unhook | |
# the ticker -- don't want the UE session to be flooded with | |
# exception handling! | |
FAILSAFE = 24 | |
# Catch string version of uncaught exceptions, so we have some | |
# forensic information if we do commit have to unhook | |
EXCEPTIONS = [] | |
STATE = {'suspend': False, 'deltatime': -1, 'init': False} | |
def _tick_function(deltatime): | |
''' | |
Exception-safe ticker which all QT widgets share | |
''' | |
if STATE['suspend']: | |
STATE['deltatime'] = -1 | |
return | |
STATE['deltatime'] = deltatime | |
try: | |
APP.processEvents() | |
except Exception: | |
error_log = traceback.format_exc() | |
EXCEPTIONS.append(error_log) | |
unreal.log_error(error_log) | |
if len(EXCEPTIONS) > FAILSAFE: | |
_tick_function.unregister() | |
_ticker = unreal.register_slate_post_tick_callback(_tick_function) | |
unreal.log("Unreal QT ticker enabled") | |
def _unregister(): | |
''' | |
In an emergency, unregister the QApplication from the unreal ticker | |
''' | |
unreal.unregister(_ticker) | |
unreal.log_warning("Unreal QT ticker disabled") | |
setattr(_tick_function, 'unregister', _unregister) | |
def ue_frame_time(): | |
""" | |
how long since the last QApp tick? | |
If the app is suspended, this will be -1 | |
""" | |
return STATE['deltatime'] | |
def application(): | |
return APP | |
def suspend(val): | |
STATE['suspend'] = val | |
unreal.log_warning('QT ticker {}'.format("ON" if not val else "OFF")) | |
def uncaught_errors(): | |
return tuple(EXCEPTIONS) | |
__all__ = 'ue_frame_time application suspend'.split() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
is there a way to increase the frequency of the widget refresh rate to make the gui more responsive?