From db125466794801a9763a75f43932c54625a0a61a Mon Sep 17 00:00:00 2001 From: Matt Gibbs Date: Thu, 25 Apr 2019 17:21:39 -0700 Subject: [PATCH 1/6] Fix bug that prevented the connection queue from ever getting used. :facepalm: --- pydm/data_plugins/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydm/data_plugins/__init__.py b/pydm/data_plugins/__init__.py index 4c1dd1ca6..22487eda4 100644 --- a/pydm/data_plugins/__init__.py +++ b/pydm/data_plugins/__init__.py @@ -39,7 +39,7 @@ def connection_queue(): def establish_connection(channel): global __CONNECTION_QUEUE__ - if __CONNECTION_QUEUE__: + if __CONNECTION_QUEUE__ is not None: __CONNECTION_QUEUE__.append(channel) else: establish_connection_immediately(channel) From fbe8cd9796009a102203f8703450ea99bdf6ca3d Mon Sep 17 00:00:00 2001 From: Matt Gibbs Date: Thu, 25 Apr 2019 17:23:00 -0700 Subject: [PATCH 2/6] Add ability to defer establishing connections to some later time. --- pydm/data_plugins/__init__.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/pydm/data_plugins/__init__.py b/pydm/data_plugins/__init__.py index 22487eda4..93bc5213b 100644 --- a/pydm/data_plugins/__init__.py +++ b/pydm/data_plugins/__init__.py @@ -11,7 +11,7 @@ import uuid from collections import deque from contextlib import contextmanager - +from qtpy.QtWidgets import QApplication from .plugin import PyDMPlugin from ..utilities import protocol_and_address from .. import config @@ -21,21 +21,36 @@ __read_only = False global __CONNECTION_QUEUE__ __CONNECTION_QUEUE__ = None +global __DEFER_CONNECTIONS__ +__DEFER_CONNECTIONS__ = False @contextmanager -def connection_queue(): +def connection_queue(defer_connections=False): global __CONNECTION_QUEUE__ + global __DEFER_CONNECTIONS__ if __CONNECTION_QUEUE__ is None: __CONNECTION_QUEUE__ = deque() + __DEFER_CONNECTIONS__ = defer_connections + yield + if __DEFER_CONNECTIONS__: + return + establish_queued_connections() + +def establish_queued_connections(): + global __DEFER_CONNECTIONS__ + global __CONNECTION_QUEUE__ + if __CONNECTION_QUEUE__ is None: + return + try: - yield - if __CONNECTION_QUEUE__ is None: - return while not len(__CONNECTION_QUEUE__) == 0: channel = __CONNECTION_QUEUE__.pop() establish_connection_immediately(channel) + QApplication.instance().processEvents() finally: __CONNECTION_QUEUE__ = None + __DEFER_CONNECTIONS__ = False + def establish_connection(channel): global __CONNECTION_QUEUE__ From 7041da944f85167bc1d6c4e1e56a19674ede4d85 Mon Sep 17 00:00:00 2001 From: Matt Gibbs Date: Thu, 25 Apr 2019 17:24:15 -0700 Subject: [PATCH 3/6] Add option to defer connections when loading displays. --- pydm/application.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydm/application.py b/pydm/application.py index 5ce1acd1c..7530605db 100644 --- a/pydm/application.py +++ b/pydm/application.py @@ -360,7 +360,7 @@ def load_py_file(self, pyfile, args=None, macros=None): kwargs['macros'] = macros return cls(**kwargs) - def open_file(self, ui_file, macros=None, command_line_args=None, **kwargs): + def open_file(self, ui_file, macros=None, command_line_args=None, defer_connections=False, **kwargs): """ Open a .ui or .py file, and return a widget from the loaded file. This method is the entry point for all opening of new displays, @@ -401,7 +401,7 @@ def open_file(self, ui_file, macros=None, command_line_args=None, **kwargs): merged_macros = self.macro_stack[-1].copy() merged_macros.update(macros) self.macro_stack.append(merged_macros) - with data_plugins.connection_queue(): + with data_plugins.connection_queue(defer_connections=defer_connections): if extension == '.ui': widget = self.load_ui_file(filepath, merged_macros) elif extension == '.py': From 5bb2af1968e095930dc356ee7efecbed88b97926 Mon Sep 17 00:00:00 2001 From: Matt Gibbs Date: Thu, 25 Apr 2019 17:25:01 -0700 Subject: [PATCH 4/6] Defer connections until after the display is loaded and visible. --- pydm/main_window.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pydm/main_window.py b/pydm/main_window.py index 933aee6e2..2ec322b5e 100644 --- a/pydm/main_window.py +++ b/pydm/main_window.py @@ -140,7 +140,7 @@ def open_abs_file(self, filename, macros=None, command_line_args=None): if command_line_args is None: command_line_args = [] merged_macros = self.merge_with_current_macros(macros) - widget = self.app.open_file(filename, merged_macros, command_line_args) + widget = self.app.open_file(filename, merged_macros, command_line_args, defer_connections=True) if (len(self.back_stack) == 0) or (self.current_file() != filename): self.back_stack.append((filename, merged_macros, command_line_args)) self.set_display_widget(widget) @@ -160,6 +160,7 @@ def open_abs_file(self, filename, macros=None, command_line_args=None): self.ui.actionEdit_in_Designer.setText(edit_in_text) if self.designer_path: self.ui.actionEdit_in_Designer.setEnabled(True) + data_plugins.establish_queued_connections() def new_window(self, ui_file, macros=None, command_line_args=None): filename = self.join_to_current_file_path(ui_file) From d6e95d0002860411463959f709731d92358e6e31 Mon Sep 17 00:00:00 2001 From: Matt Gibbs Date: Fri, 26 Apr 2019 13:32:22 -0700 Subject: [PATCH 5/6] Use deferred connections in template repeater. --- pydm/widgets/template_repeater.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pydm/widgets/template_repeater.py b/pydm/widgets/template_repeater.py index 34f06edb8..cf1d2e625 100644 --- a/pydm/widgets/template_repeater.py +++ b/pydm/widgets/template_repeater.py @@ -328,7 +328,7 @@ def rebuild(self): QWidget().setLayout(self.layout()) l = layout_class(self) self.setLayout(l) - with pydm.data_plugins.connection_queue(): + with pydm.data_plugins.connection_queue(defer_connections=True): for i, variables in enumerate(self.data): if is_qt_designer() and i > self.countShownInDesigner - 1: break @@ -339,6 +339,7 @@ def rebuild(self): w.setParent(self) self.layout().addWidget(w) self.setUpdatesEnabled(True) + pydm.data_plugins.establish_queued_connections() def clear(self): """ Clear out any existing instances of the template inside From 80e1194f7b6f571536dbeae06f04a64c9e412ed6 Mon Sep 17 00:00:00 2001 From: Matt Gibbs Date: Fri, 26 Apr 2019 13:33:18 -0700 Subject: [PATCH 6/6] Empty the connection queue in LIFO order. --- pydm/data_plugins/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pydm/data_plugins/__init__.py b/pydm/data_plugins/__init__.py index 93bc5213b..1f09f29d3 100644 --- a/pydm/data_plugins/__init__.py +++ b/pydm/data_plugins/__init__.py @@ -41,10 +41,9 @@ def establish_queued_connections(): global __CONNECTION_QUEUE__ if __CONNECTION_QUEUE__ is None: return - try: while not len(__CONNECTION_QUEUE__) == 0: - channel = __CONNECTION_QUEUE__.pop() + channel = __CONNECTION_QUEUE__.popleft() establish_connection_immediately(channel) QApplication.instance().processEvents() finally: