diff --git a/pydm/display.py b/pydm/display.py index 8427929f1..c3f5b9d7e 100644 --- a/pydm/display.py +++ b/pydm/display.py @@ -116,6 +116,14 @@ def _load_ui_into_display(uifile, display): display.ui = display +def clear_compiled_ui_file_cache() -> None: + """ + Clears the cache of compiled ui files. Needed if changes to the underlying ui files have been made on disk and + need to be picked up, such as the user choosing to reload the display. + """ + _compile_ui_file.cache_clear() + + def _load_compiled_ui_into_display( code_string: str, class_name: str, display: Display, macros: Optional[Dict[str, str]] = None ) -> None: diff --git a/pydm/main_window.py b/pydm/main_window.py index 40239733e..0af492370 100644 --- a/pydm/main_window.py +++ b/pydm/main_window.py @@ -6,7 +6,7 @@ from qtpy.QtGui import QKeySequence from .utilities import IconFont, find_file, establish_widget_connections, close_widget_connections from .pydm_ui import Ui_MainWindow -from .display import Display, ScreenTarget, load_file +from .display import Display, ScreenTarget, load_file, clear_compiled_ui_file_cache from .connection_inspector import ConnectionInspector from .about_pydm import AboutWindow from .show_macros import MacroWindow @@ -442,6 +442,7 @@ def reload_display(self, checked): loaded_file = curr_display.loaded_file() self.statusBar().showMessage("Reloading '{0}'...".format(self.current_file()), 5000) + clear_compiled_ui_file_cache() new_widget = self.open(loaded_file, macros=macros, args=args) new_widget.previous_display = prev_display new_widget.next_display = next_display diff --git a/pydm/tests/test_main_window.py b/pydm/tests/test_main_window.py new file mode 100644 index 000000000..a0d537745 --- /dev/null +++ b/pydm/tests/test_main_window.py @@ -0,0 +1,30 @@ +import os + +from pydm import PyDMApplication +from pydm.display import Display, clear_compiled_ui_file_cache +from qtpy import uic +from unittest.mock import MagicMock, patch + +# The path to the .ui file for creating a main window +test_ui_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_data", "test.ui") + + +@patch("qtpy.uic.compileUi", wraps=uic.compileUi) +def test_reload_display(wrapped_compile_ui: MagicMock, qapp: PyDMApplication) -> None: + """Verify that when a user reloads a PyDM window the underling display's ui file is actually reloaded""" + clear_compiled_ui_file_cache() # Ensure other tests have not already compiled our test file before we start + + try: + display = Display(parent=None, ui_filename=test_ui_path) + + qapp.make_main_window() + qapp.main_window.set_display_widget(display) + + # When the display is first created and loaded the underlying ui file gets compiled + wrapped_compile_ui.assert_called_once() + + # Reloading should force a re-compile of the ui file to ensure any changes are picked up + qapp.main_window.reload_display(True) + assert wrapped_compile_ui.call_count == 2 + finally: + clear_compiled_ui_file_cache()