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
|
||||
stateChange = pyqtSignal(str, bool, str) # node name, online, connection state
|
||||
unhandledMsg = pyqtSignal(str) # message
|
||||
descriptionChanged = pyqtSignal(str, object) # contactpoint, self
|
||||
logEntry = pyqtSignal(str)
|
||||
|
||||
def __init__(self, uri, parent_logger, parent=None):
|
||||
@ -48,7 +49,7 @@ class QSECNode(QObject):
|
||||
self.protocolVersion = conn.secop_version
|
||||
self.log.debug('SECoP Version: %s', conn.secop_version)
|
||||
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
|
||||
def reconnect(self):
|
||||
@ -106,5 +107,10 @@ class QSECNode(QObject):
|
||||
def unhandledMessage(self, action, specifier, data):
|
||||
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):
|
||||
self.conn.disconnect()
|
||||
|
@ -229,6 +229,7 @@ class MainWindow(QMainWindow):
|
||||
self.tab.addTab(nodeWidget, node.equipmentId)
|
||||
self._nodeWidgets[host] = nodeWidget
|
||||
self.tab.setCurrentWidget(nodeWidget)
|
||||
node.descriptionChanged.connect(self._descriptiveDataChange)
|
||||
|
||||
# add to recent nodes
|
||||
settings = QSettings()
|
||||
@ -275,6 +276,16 @@ class MainWindow(QMainWindow):
|
||||
self.log.debug("Closing tab with node %s", node.nodename)
|
||||
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):
|
||||
if advanced:
|
||||
pass
|
||||
|
@ -170,7 +170,18 @@ class ModuleOverview(QTreeWidget):
|
||||
module.disconnected()
|
||||
|
||||
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():
|
||||
if mname not in nodemods:
|
||||
return # description changed and we will be replaced, return early
|
||||
cache = self._node.queryCache(mname)
|
||||
if not 'status' in cache:
|
||||
module.setClearIcon()
|
||||
|
@ -296,6 +296,7 @@ class TearOffTabWidget(QTabWidget):
|
||||
for i in self.tabIdx.values():
|
||||
if i.widget == w:
|
||||
detachWindow.tabIdx = self.tabIdx[i.index].index
|
||||
self.tabIdx[i.index].detached = detachWindow
|
||||
break
|
||||
|
||||
detachWindow.closed.connect(self.attachTab)
|
||||
@ -383,6 +384,9 @@ class TearOffTabWidget(QTabWidget):
|
||||
if newIndex != -1:
|
||||
self.setCurrentIndex(newIndex)
|
||||
|
||||
idx = self.find_widget(tearOffWidget)
|
||||
self.tabIdx[idx].detached = None
|
||||
|
||||
def tabChangedTab(self, index):
|
||||
# for i in range(self.count()):
|
||||
# for p in self.widget(i).panels:
|
||||
@ -463,6 +467,29 @@ class TearOffTabWidget(QTabWidget):
|
||||
# # QByteArray))
|
||||
# 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):
|
||||
widget = w
|
||||
while True:
|
||||
|
Loading…
x
Reference in New Issue
Block a user