Rebuild NodeWidget when the description changes
+ add descriptionChanged signal * track detached of TabWidgetStorage correctly * build new NodeWidget when the nodes description changes. the old one is replaced Change-Id: I61e60c61b7c2c975819730cb98562657a66f16af Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/30910 Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de> Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de> Reviewed-by: Alexander Zaft <a.zaft@fz-juelich.de>
This commit is contained in:
parent
f069b31d5a
commit
42c5e97122
@ -30,6 +30,7 @@ class QSECNode(QObject):
|
|||||||
newData = pyqtSignal(str, str, object) # module, parameter, data
|
newData = pyqtSignal(str, str, object) # module, parameter, data
|
||||||
stateChange = pyqtSignal(str, bool, str) # node name, online, connection state
|
stateChange = pyqtSignal(str, bool, str) # node name, online, connection state
|
||||||
unhandledMsg = pyqtSignal(str) # message
|
unhandledMsg = pyqtSignal(str) # message
|
||||||
|
descriptionChanged = pyqtSignal(str, object) # contactpoint, self
|
||||||
logEntry = pyqtSignal(str)
|
logEntry = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, uri, parent_logger, parent=None):
|
def __init__(self, uri, parent_logger, parent=None):
|
||||||
@ -48,7 +49,7 @@ class QSECNode(QObject):
|
|||||||
self.protocolVersion = conn.secop_version
|
self.protocolVersion = conn.secop_version
|
||||||
self.log.debug('SECoP Version: %s', conn.secop_version)
|
self.log.debug('SECoP Version: %s', conn.secop_version)
|
||||||
conn.register_callback(None, self.updateItem, self.nodeStateChange,
|
conn.register_callback(None, self.updateItem, self.nodeStateChange,
|
||||||
self.unhandledMessage)
|
self.unhandledMessage, self.descriptiveDataChange)
|
||||||
|
|
||||||
# provide methods from old baseclient for making other gui code work
|
# provide methods from old baseclient for making other gui code work
|
||||||
def reconnect(self):
|
def reconnect(self):
|
||||||
@ -106,5 +107,10 @@ class QSECNode(QObject):
|
|||||||
def unhandledMessage(self, action, specifier, data):
|
def unhandledMessage(self, action, specifier, data):
|
||||||
self.unhandledMsg.emit(f'{action} {specifier} {data!r}')
|
self.unhandledMsg.emit(f'{action} {specifier} {data!r}')
|
||||||
|
|
||||||
|
def descriptiveDataChange(self, _module, conn):
|
||||||
|
self.modules = conn.modules
|
||||||
|
self.properties = conn.properties
|
||||||
|
self.descriptionChanged.emit(self.contactPoint, self)
|
||||||
|
|
||||||
def terminate_connection(self):
|
def terminate_connection(self):
|
||||||
self.conn.disconnect()
|
self.conn.disconnect()
|
||||||
|
@ -229,6 +229,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.tab.addTab(nodeWidget, node.equipmentId)
|
self.tab.addTab(nodeWidget, node.equipmentId)
|
||||||
self._nodeWidgets[host] = nodeWidget
|
self._nodeWidgets[host] = nodeWidget
|
||||||
self.tab.setCurrentWidget(nodeWidget)
|
self.tab.setCurrentWidget(nodeWidget)
|
||||||
|
node.descriptionChanged.connect(self._descriptiveDataChange)
|
||||||
|
|
||||||
# add to recent nodes
|
# add to recent nodes
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
@ -275,6 +276,16 @@ class MainWindow(QMainWindow):
|
|||||||
self.log.debug("Closing tab with node %s", node.nodename)
|
self.log.debug("Closing tab with node %s", node.nodename)
|
||||||
self.tab.removeTab(index)
|
self.tab.removeTab(index)
|
||||||
|
|
||||||
|
def _descriptiveDataChange(self, host, node):
|
||||||
|
old_widget = self._nodeWidgets[host]
|
||||||
|
new_widget = NodeWidget(node)
|
||||||
|
curr_idx = self.tab.currentIndex()
|
||||||
|
index = self.tab.indexOf(old_widget)
|
||||||
|
self._nodeWidgets[host] = new_widget
|
||||||
|
self.tab.replace_widget(old_widget, new_widget, title=node.equipmentId)
|
||||||
|
if curr_idx == index:
|
||||||
|
self.tab.setCurrentIndex(curr_idx)
|
||||||
|
|
||||||
def _rebuildAdvanced(self, advanced):
|
def _rebuildAdvanced(self, advanced):
|
||||||
if advanced:
|
if advanced:
|
||||||
pass
|
pass
|
||||||
|
@ -170,7 +170,18 @@ class ModuleOverview(QTreeWidget):
|
|||||||
module.disconnected()
|
module.disconnected()
|
||||||
|
|
||||||
def setToReconnected(self):
|
def setToReconnected(self):
|
||||||
|
"""set status after connection is reestablished.
|
||||||
|
|
||||||
|
If the node-description has changed during the reconnection, the nodewidget
|
||||||
|
this overview is a part of gets replaced. However, the reconnect-event
|
||||||
|
gets through before the descriptionChanged-event. So if a module is no
|
||||||
|
longer present we return early in order to avoid KeyErrors on node.modules
|
||||||
|
For the case of additional modules or changed module contents we do not care.
|
||||||
|
"""
|
||||||
|
nodemods = self._node.modules.keys()
|
||||||
for mname, module in self._modules.items():
|
for mname, module in self._modules.items():
|
||||||
|
if mname not in nodemods:
|
||||||
|
return # description changed and we will be replaced, return early
|
||||||
cache = self._node.queryCache(mname)
|
cache = self._node.queryCache(mname)
|
||||||
if not 'status' in cache:
|
if not 'status' in cache:
|
||||||
module.setClearIcon()
|
module.setClearIcon()
|
||||||
|
@ -296,6 +296,7 @@ class TearOffTabWidget(QTabWidget):
|
|||||||
for i in self.tabIdx.values():
|
for i in self.tabIdx.values():
|
||||||
if i.widget == w:
|
if i.widget == w:
|
||||||
detachWindow.tabIdx = self.tabIdx[i.index].index
|
detachWindow.tabIdx = self.tabIdx[i.index].index
|
||||||
|
self.tabIdx[i.index].detached = detachWindow
|
||||||
break
|
break
|
||||||
|
|
||||||
detachWindow.closed.connect(self.attachTab)
|
detachWindow.closed.connect(self.attachTab)
|
||||||
@ -383,6 +384,9 @@ class TearOffTabWidget(QTabWidget):
|
|||||||
if newIndex != -1:
|
if newIndex != -1:
|
||||||
self.setCurrentIndex(newIndex)
|
self.setCurrentIndex(newIndex)
|
||||||
|
|
||||||
|
idx = self.find_widget(tearOffWidget)
|
||||||
|
self.tabIdx[idx].detached = None
|
||||||
|
|
||||||
def tabChangedTab(self, index):
|
def tabChangedTab(self, index):
|
||||||
# for i in range(self.count()):
|
# for i in range(self.count()):
|
||||||
# for p in self.widget(i).panels:
|
# for p in self.widget(i).panels:
|
||||||
@ -463,6 +467,29 @@ class TearOffTabWidget(QTabWidget):
|
|||||||
# # QByteArray))
|
# # QByteArray))
|
||||||
# detachWindow.show()
|
# detachWindow.show()
|
||||||
|
|
||||||
|
def find_widget(self, widget):
|
||||||
|
for idx, tab in self.tabIdx.items():
|
||||||
|
if tab.widget == widget:
|
||||||
|
return idx
|
||||||
|
return None
|
||||||
|
|
||||||
|
def replace_widget(self, old_widget, new_widget, title=None):
|
||||||
|
"""If old_widget is a child of either a tab or a detached window, it will
|
||||||
|
be replaced by new_widget"""
|
||||||
|
idx = self.find_widget(old_widget)
|
||||||
|
if not idx:
|
||||||
|
return
|
||||||
|
wstore = self.tabIdx[idx]
|
||||||
|
if title:
|
||||||
|
wstore.title = title
|
||||||
|
if wstore.detached:
|
||||||
|
wstore.detached.setWidget(new_widget)
|
||||||
|
else:
|
||||||
|
tabi = self._tabWidgetIndex(old_widget)
|
||||||
|
self.removeTab(tabi)
|
||||||
|
self.insertTab(tabi, new_widget, wstore.title)
|
||||||
|
wstore.widget = new_widget
|
||||||
|
|
||||||
def topLevelWidget(self, w):
|
def topLevelWidget(self, w):
|
||||||
widget = w
|
widget = w
|
||||||
while True:
|
while True:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user