Bug hunting and polishing
Change-Id: I0f05730dd4e01e926ab0c4870c27ed5754f3ccfd
This commit is contained in:
@ -27,6 +27,7 @@ from PyQt4.QtCore import pyqtSignature as qtsig, QObject, pyqtSignal
|
||||
from secop.gui.util import loadUi
|
||||
from secop.gui.nodectrl import NodeCtrl
|
||||
from secop.gui.modulectrl import ModuleCtrl
|
||||
from secop.gui.paramview import ParameterView
|
||||
from secop.client.baseclient import Client as SECNode
|
||||
|
||||
ITEM_TYPE_NODE = QTreeWidgetItem.UserType + 1
|
||||
@ -35,7 +36,7 @@ ITEM_TYPE_PARAMETER = QTreeWidgetItem.UserType + 3
|
||||
|
||||
|
||||
class QSECNode(SECNode, QObject):
|
||||
newData = pyqtSignal(str, str, object) # module, parameter, data
|
||||
newData = pyqtSignal(str, str, object) # module, parameter, data
|
||||
|
||||
def __init__(self, opts, autoconnect=False, parent=None):
|
||||
SECNode.__init__(self, opts, autoconnect)
|
||||
@ -79,7 +80,7 @@ class MainWindow(QMainWindow):
|
||||
@qtsig('')
|
||||
def on_actionAdd_SEC_node_triggered(self):
|
||||
host, ok = QInputDialog.getText(self, 'Add SEC node',
|
||||
'Enter SEC node hostname:')
|
||||
'Enter SEC node hostname:')
|
||||
|
||||
if not ok:
|
||||
return
|
||||
@ -91,6 +92,10 @@ class MainWindow(QMainWindow):
|
||||
self._displayNode(current.text(0))
|
||||
elif current.type() == ITEM_TYPE_MODULE:
|
||||
self._displayModule(current.parent().text(0), current.text(0))
|
||||
elif current.type() == ITEM_TYPE_PARAMETER:
|
||||
self._displayParameter(current.parent().parent().text(0),
|
||||
current.parent().text(0),
|
||||
current.text(0))
|
||||
|
||||
def _addNode(self, host):
|
||||
|
||||
@ -99,9 +104,10 @@ class MainWindow(QMainWindow):
|
||||
if ':' in host:
|
||||
host, port = host.split(':', 1)
|
||||
port = int(port)
|
||||
node = QSECNode({'connectto':host, 'port':port}, parent=self)
|
||||
node = QSECNode({'connectto': host, 'port': port}, parent=self)
|
||||
host = '%s:%d' % (host, port)
|
||||
|
||||
host = '%s (%s)' % (node.equipment_id, host)
|
||||
self._nodes[host] = node
|
||||
|
||||
# fill tree
|
||||
@ -127,6 +133,13 @@ class MainWindow(QMainWindow):
|
||||
def _displayModule(self, node, module):
|
||||
self._replaceCtrlWidget(ModuleCtrl(self._nodes[node], module))
|
||||
|
||||
def _displayParameter(self, node, module, parameter):
|
||||
self._replaceCtrlWidget(
|
||||
ParameterView(
|
||||
self._nodes[node],
|
||||
module,
|
||||
parameter))
|
||||
|
||||
def _replaceCtrlWidget(self, new):
|
||||
old = self.splitter.widget(1).layout().takeAt(0)
|
||||
if old:
|
||||
|
@ -26,10 +26,12 @@ from PyQt4.QtCore import pyqtSignature as qtsig, Qt, pyqtSignal
|
||||
|
||||
from secop.gui.util import loadUi
|
||||
|
||||
class ParameterButtons(QWidget):
|
||||
setRequested = pyqtSignal(str, str, str) # module, parameter, setpoint
|
||||
|
||||
def __init__(self, module, parameter, initval='', parent=None):
|
||||
class ParameterButtons(QWidget):
|
||||
setRequested = pyqtSignal(str, str, str) # module, parameter, target
|
||||
|
||||
def __init__(self, module, parameter, initval='',
|
||||
readonly=True, parent=None):
|
||||
super(ParameterButtons, self).__init__(parent)
|
||||
loadUi(self, 'parambuttons.ui')
|
||||
|
||||
@ -37,20 +39,24 @@ class ParameterButtons(QWidget):
|
||||
self._parameter = parameter
|
||||
|
||||
self.currentLineEdit.setText(str(initval))
|
||||
if readonly:
|
||||
self.setPushButton.setEnabled(False)
|
||||
self.setLineEdit.setEnabled(False)
|
||||
|
||||
def on_setPushButton_clicked(self):
|
||||
self.setRequested.emit(self._module, self._parameter,
|
||||
self.setLineEdit.text())
|
||||
self.setLineEdit.text())
|
||||
|
||||
|
||||
class ModuleCtrl(QWidget):
|
||||
|
||||
def __init__(self, node, module, parent=None):
|
||||
super(ModuleCtrl, self).__init__(parent)
|
||||
loadUi(self, 'modulectrl.ui')
|
||||
self._node = node
|
||||
self._module = module
|
||||
|
||||
self._paramWidgets = {} # widget cache do avoid garbage collection
|
||||
self._paramWidgets = {} # widget cache do avoid garbage collection
|
||||
|
||||
self.moduleNameLabel.setText(module)
|
||||
self._initModuleWidgets()
|
||||
@ -68,8 +74,12 @@ class ModuleCtrl(QWidget):
|
||||
label = QLabel(param + ':')
|
||||
label.setFont(font)
|
||||
|
||||
props = self._node.getProperties(self._module, param)
|
||||
|
||||
buttons = ParameterButtons(self._module, param,
|
||||
initValues[param].value)
|
||||
initValues[param].value,
|
||||
props['readonly'])
|
||||
|
||||
buttons.setRequested.connect(self._node.setParameter)
|
||||
|
||||
self.paramGroupBox.layout().addWidget(label, row, 0)
|
||||
|
@ -27,8 +27,11 @@ from PyQt4.QtGui import QWidget, QTextCursor, QFont, QFontMetrics
|
||||
from PyQt4.QtCore import pyqtSignature as qtsig, Qt
|
||||
|
||||
from secop.gui.util import loadUi
|
||||
from secop.protocol.errors import SECOPError
|
||||
|
||||
|
||||
class NodeCtrl(QWidget):
|
||||
|
||||
def __init__(self, node, parent=None):
|
||||
super(NodeCtrl, self).__init__(parent)
|
||||
loadUi(self, 'nodectrl.ui')
|
||||
@ -49,9 +52,12 @@ class NodeCtrl(QWidget):
|
||||
|
||||
self._addLogEntry('<span style="font-weight:bold">Request:</span> '
|
||||
'%s:' % msg, raw=True)
|
||||
msg = msg.split(' ', 2)
|
||||
reply = self._node.syncCommunicate(*msg)
|
||||
self._addLogEntry(reply, newline=True, pretty=True)
|
||||
# msg = msg.split(' ', 2)
|
||||
try:
|
||||
reply = self._node.syncCommunicate(*self._node.decode_message(msg))
|
||||
self._addLogEntry(reply, newline=True, pretty=True)
|
||||
except SECOPError as e:
|
||||
self._addLogEntry(e, newline=True, pretty=True, error=True)
|
||||
|
||||
@qtsig('')
|
||||
def on_clearPushButton_clicked(self):
|
||||
@ -64,13 +70,19 @@ class NodeCtrl(QWidget):
|
||||
self._addLogEntry('=========================')
|
||||
self._addLogEntry('', newline=True)
|
||||
|
||||
def _addLogEntry(self, msg, newline=False, pretty=False, raw=False):
|
||||
def _addLogEntry(self, msg, newline=False,
|
||||
pretty=False, raw=False, error=False):
|
||||
|
||||
if pretty:
|
||||
msg = pprint.pformat(msg, width=self._getLogWidth())
|
||||
|
||||
if not raw:
|
||||
msg = '<pre>%s</pre>' % Qt.escape(str(msg)).replace('\n', '<br />')
|
||||
if error:
|
||||
msg = '<div style="color:#FF0000"><b><pre>%s</pre></b></div>' % Qt.escape(
|
||||
str(msg)).replace('\n', '<br />')
|
||||
else:
|
||||
msg = '<pre>%s</pre>' % Qt.escape(str(msg)
|
||||
).replace('\n', '<br />')
|
||||
|
||||
content = ''
|
||||
if self.logTextBrowser.toPlainText():
|
||||
@ -89,4 +101,3 @@ class NodeCtrl(QWidget):
|
||||
# due to monospace)
|
||||
result = self.logTextBrowser.width() / fontMetrics.width('a')
|
||||
return result
|
||||
|
||||
|
81
secop/gui/paramview.py
Normal file
81
secop/gui/paramview.py
Normal file
@ -0,0 +1,81 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# *****************************************************************************
|
||||
# Copyright (c) 2015-2017 by the authors, see LICENSE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# Module authors:
|
||||
# Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
|
||||
#
|
||||
# *****************************************************************************
|
||||
|
||||
from PyQt4.QtGui import QWidget, QLabel, QSizePolicy
|
||||
from PyQt4.QtCore import pyqtSignature as qtsig, Qt, pyqtSignal
|
||||
|
||||
from secop.gui.util import loadUi
|
||||
from secop.validators import validator_to_str
|
||||
|
||||
|
||||
class ParameterView(QWidget):
|
||||
|
||||
def __init__(self, node, module, parameter, parent=None):
|
||||
super(ParameterView, self).__init__(parent)
|
||||
loadUi(self, 'paramview.ui')
|
||||
self._node = node
|
||||
self._module = module
|
||||
self._parameter = parameter
|
||||
|
||||
self._propWidgets = {} # widget cache do avoid garbage collection
|
||||
|
||||
self.paramNameLabel.setText("%s:%s" % (module, parameter))
|
||||
self._initParamWidgets()
|
||||
|
||||
# self._node.newData.connect(self._updateValue)
|
||||
|
||||
def _initParamWidgets(self):
|
||||
# initValues = self._node.queryCache(self._module) #? mix live data?
|
||||
row = 0
|
||||
|
||||
font = self.font()
|
||||
font.setBold(True)
|
||||
|
||||
props = self._node._getDescribingParameterData(
|
||||
self._module, self._parameter)
|
||||
for prop in sorted(props):
|
||||
label = QLabel(prop + ':')
|
||||
label.setFont(font)
|
||||
label.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
|
||||
# make 'display' label
|
||||
if prop == 'validator':
|
||||
view = QLabel(validator_to_str(props[prop]))
|
||||
else:
|
||||
view = QLabel(str(props[prop]))
|
||||
view.setFont(self.font())
|
||||
view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
view.setWordWrap(True)
|
||||
|
||||
self.propertyGroupBox.layout().addWidget(label, row, 0)
|
||||
self.propertyGroupBox.layout().addWidget(view, row, 1)
|
||||
|
||||
self._propWidgets[prop] = (label, view)
|
||||
|
||||
row += 1
|
||||
|
||||
def _updateValue(self, module, parameter, value):
|
||||
if module != self._module:
|
||||
return
|
||||
|
||||
self._paramWidgets[parameter][1].currentLineEdit.setText(str(value[0]))
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>730</width>
|
||||
<height>31</height>
|
||||
<height>33</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -33,7 +33,7 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="currentLineEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -41,6 +41,9 @@
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
|
99
secop/gui/ui/paramview.ui
Normal file
99
secop/gui/ui/paramview.ui
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>230</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Parameter name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="paramNameLabel">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="propertyGroupBox">
|
||||
<property name="title">
|
||||
<string>Parameters:</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Reference in New Issue
Block a user