Support PyQt5 (fallback to PyQt4)

Change-Id: I7fa1add00d677e626fee5cd1071dee54d0bf8565
Reviewed-on: https://forge.frm2.tum.de/review/17666
Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de>
Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
Tested-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
This commit is contained in:
Enrico Faulhaber 2018-04-11 11:10:22 +02:00
parent 40e75aefcc
commit e830666315
9 changed files with 84 additions and 80 deletions

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# pylint: disable=invalid-name
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# ***************************************************************************** # *****************************************************************************
# Copyright (c) 2015-2016 by the authors, see LICENSE # Copyright (c) 2015-2016 by the authors, see LICENSE
@ -27,15 +28,13 @@ from __future__ import print_function
import sys import sys
from os import path from os import path
# Add import path for inplace usage # Add import path for inplace usage
sys.path.insert(0, path.abspath(path.join(path.dirname(__file__), '..'))) sys.path.insert(0, path.abspath(path.join(path.dirname(__file__), '..')))
from secop.gui.mainwindow import MainWindow
import mlzlog import mlzlog
from PyQt4.QtGui import QApplication from secop.gui.qt import QApplication
from secop.gui.mainwindow import MainWindow
def main(argv=None): def main(argv=None):
@ -67,4 +66,3 @@ def main(argv=None):
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main(sys.argv)) sys.exit(main(sys.argv))

View File

@ -25,8 +25,8 @@ from __future__ import print_function
import sys import sys
from PyQt4.QtGui import QMainWindow, QInputDialog, QTreeWidgetItem, QMessageBox from secop.gui.qt import QMainWindow, QInputDialog, QTreeWidgetItem, QMessageBox, \
from PyQt4.QtCore import pyqtSignature as qtsig, QObject, pyqtSignal pyqtSlot, QObject, pyqtSignal
from secop.gui.util import loadUi from secop.gui.util import loadUi
from secop.gui.nodectrl import NodeCtrl from secop.gui.nodectrl import NodeCtrl
@ -98,7 +98,7 @@ class MainWindow(QMainWindow):
except Exception as e: except Exception as e:
print(e) print(e)
@qtsig('') @pyqtSlot()
def on_actionAdd_SEC_node_triggered(self): def on_actionAdd_SEC_node_triggered(self):
host, ok = QInputDialog.getText(self, 'Add SEC node', host, ok = QInputDialog.getText(self, 'Add SEC node',
'Enter SEC node hostname:') 'Enter SEC node hostname:')

View File

@ -18,22 +18,19 @@
# #
# Module authors: # Module authors:
# Alexander Lenz <alexander.lenz@frm2.tum.de> # Alexander Lenz <alexander.lenz@frm2.tum.de>
# Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
# #
# ***************************************************************************** # *****************************************************************************
from __future__ import print_function from __future__ import print_function
from PyQt4.QtGui import QWidget, QLabel, QPushButton as QButton, QLineEdit, QMessageBox, QCheckBox, QSizePolicy, QDialog
from PyQt4.QtCore import pyqtSignature as qtsig, Qt, pyqtSignal
from secop.gui.util import loadUi from secop.gui.util import loadUi
from secop.gui.params import ParameterView from secop.gui.params import ParameterView
from secop.datatypes import * from secop.datatypes import * # pylint: disable=unused-wildcard-import,wildcard-import
from PyQt4.QtGui import QDialog, QPushButton, QLabel, QApplication, QLineEdit,\ from secop.gui.qt import QDialog, QLabel, QCheckBox, QWidget, QMessageBox, \
QGroupBox, QSpinBox, QDoubleSpinBox, QComboBox, QCheckBox, QRadioButton, \ QPushButton, QSizePolicy
QVBoxLayout, QGridLayout, QScrollArea, QFrame
from secop.gui.valuewidgets import get_widget from secop.gui.valuewidgets import get_widget
@ -67,7 +64,7 @@ class CommandDialog(QDialog):
def exec_(self): def exec_(self):
if super(CommandDialog, self).exec_(): if super(CommandDialog, self).exec_():
return self.get_value() return self.get_value()
return None
def showCommandResultDialog(command, args, result, extras=''): def showCommandResultDialog(command, args, result, extras=''):
@ -117,7 +114,7 @@ class ParameterGroup(QWidget):
w.hide() w.hide()
class CommandButton(QButton): class CommandButton(QPushButton):
def __init__(self, cmdname, cmdinfo, cb, parent=None): def __init__(self, cmdname, cmdinfo, cb, parent=None):
super(CommandButton, self).__init__(parent) super(CommandButton, self).__init__(parent)

View File

@ -25,8 +25,8 @@ import pprint
import json import json
from time import sleep from time import sleep
from PyQt4.QtGui import QWidget, QTextCursor, QFont, QFontMetrics, QLabel, QMessageBox from secop.gui.qt import QWidget, QTextCursor, QFont, QFontMetrics, QLabel, \
from PyQt4.QtCore import pyqtSignature as qtsig, Qt QMessageBox, pyqtSlot, toHtmlEscaped
from secop.gui.util import loadUi from secop.gui.util import loadUi
from secop.protocol.errors import SECOPError from secop.protocol.errors import SECOPError
@ -51,7 +51,7 @@ class NodeCtrl(QWidget):
# now populate modules tab # now populate modules tab
self._init_modules_tab() self._init_modules_tab()
@qtsig('') @pyqtSlot()
def on_sendPushButton_clicked(self): def on_sendPushButton_clicked(self):
msg = self.msgLineEdit.text().strip() msg = self.msgLineEdit.text().strip()
@ -79,7 +79,7 @@ class NodeCtrl(QWidget):
pretty=True, pretty=True,
error=True) error=True)
@qtsig('') @pyqtSlot()
def on_clearPushButton_clicked(self): def on_clearPushButton_clicked(self):
self._clearLog() self._clearLog()
@ -102,11 +102,11 @@ class NodeCtrl(QWidget):
if not raw: if not raw:
if error: if error:
msg = '<div style="color:#FF0000"><b><pre>%s</pre></b></div>' % Qt.escape( msg = '<div style="color:#FF0000"><b><pre>%s</pre></b></div>' % toHtmlEscaped(
str(msg)).replace('\n', '<br />') str(msg)).replace('\n', '<br />')
else: else:
msg = '<pre>%s</pre>' % Qt.escape(str(msg)).replace('\n', msg = '<pre>%s</pre>' % toHtmlEscaped(
'<br />') str(msg)).replace('\n', '<br />')
content = '' content = ''
if self.logTextBrowser.toPlainText(): if self.logTextBrowser.toPlainText():

View File

@ -21,11 +21,11 @@
# #
# ***************************************************************************** # *****************************************************************************
from PyQt4.QtGui import QWidget, QLabel, QPushButton as QButton, QLineEdit, QMessageBox, QCheckBox, QSizePolicy from secop.gui.qt import QWidget, QLabel, QPushButton as QButton, QLineEdit, \
from PyQt4.QtCore import pyqtSignature as qtsig, Qt, pyqtSignal QMessageBox, QCheckBox, QSizePolicy, Qt, pyqtSignal
from secop.gui.util import loadUi from secop.gui.util import loadUi
from secop.datatypes import * from secop.datatypes import * # pylint: disable=wildcard-import
class ParameterWidget(QWidget): class ParameterWidget(QWidget):
@ -88,11 +88,11 @@ class EnumParameterWidget(GenericParameterWidget):
self._map = {} # maps index to enumstring self._map = {} # maps index to enumstring
self._revmap = {} # maps enumstring to index self._revmap = {} # maps enumstring to index
index = 0 index = 0
for data, entry in sorted(self._datatype.entries.items()): for enumval, enumname in sorted(self._datatype.entries.items()):
self.setComboBox.addItem(entry, data) self.setComboBox.addItem(enumname, enumval)
self._map[index] = entry self._map[index] = (enumval, enumname)
self._revmap[entry] = index self._revmap[enumname] = index
self._revmap[data] = index self._revmap[enumval] = index
index += 1 index += 1
if self._readonly: if self._readonly:
self.setLabel.setEnabled(False) self.setLabel.setEnabled(False)
@ -105,18 +105,19 @@ class EnumParameterWidget(GenericParameterWidget):
self.updateValue(str(initvalue)) self.updateValue(str(initvalue))
def on_setPushButton_clicked(self): def on_setPushButton_clicked(self):
self.setRequested.emit( enumval, enumname = self._map[self.setComboBox.currentIndex()]
self._module, self._paramcmd, str( self.setRequested.emit(self._module, self._paramcmd, enumname)
self._datatype.reversed[ self.setRequested.emit(self._module, self._paramcmd, str(enumval))
self._map[
self.setComboBox.currentIndex()]]))
def updateValue(self, valuestr): def updateValue(self, valuestr):
try: try:
self.currentLineEdit.setText( valuestr = int(valuestr)
self._datatype.entries.get(
int(valuestr), valuestr))
except ValueError: except ValueError:
pass
if valuestr in self._revmap:
index = self._revmap[valuestr]
self.currentLineEdit.setText('(%d): %s' % self._map[index])
else:
self.currentLineEdit.setText('undefined Value: %r' % valuestr) self.currentLineEdit.setText('undefined Value: %r' % valuestr)

View File

@ -21,11 +21,10 @@
# #
# ***************************************************************************** # *****************************************************************************
from PyQt4.QtGui import QWidget, QLabel, QSizePolicy from secop.gui.qt import QWidget, QLabel, QSizePolicy
from PyQt4.QtCore import pyqtSignature as qtsig, Qt, pyqtSignal
from secop.gui.util import loadUi from secop.gui.util import loadUi
from secop.datatypes import get_datatype #from secop.datatypes import get_datatype
class ParameterView(QWidget): class ParameterView(QWidget):

25
secop/gui/qt.py Normal file
View File

@ -0,0 +1,25 @@
# pylint: disable=unused-import
from __future__ import print_function
try:
from PyQt5 import uic
from PyQt5.QtCore import Qt, QObject, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QFont, QTextCursor, QFontMetrics
from PyQt5.QtWidgets import QLabel, QWidget, QDialog, QLineEdit, QCheckBox, QPushButton, \
QSizePolicy, QMainWindow, QMessageBox, QInputDialog, QTreeWidgetItem, QApplication, \
QGroupBox, QSpinBox, QDoubleSpinBox, QComboBox, QRadioButton, QVBoxLayout, QHBoxLayout, \
QGridLayout, QScrollArea, QFrame
from xml.sax.saxutils import escape as toHtmlEscaped
except ImportError:
from PyQt4 import uic
from PyQt4.QtCore import Qt, QObject, pyqtSignal, pyqtSlot
from PyQt4.QtGui import QFont, QTextCursor, QFontMetrics, \
QLabel, QWidget, QDialog, QLineEdit, QCheckBox, QPushButton, \
QSizePolicy, QMainWindow, QMessageBox, QInputDialog, QTreeWidgetItem, QApplication, \
QGroupBox, QSpinBox, QDoubleSpinBox, QComboBox, QRadioButton, QVBoxLayout, QHBoxLayout, \
QGridLayout, QScrollArea, QFrame
def toHtmlEscaped(s):
return Qt.escape(s)

View File

@ -23,7 +23,7 @@
from os import path from os import path
from PyQt4 import uic from secop.gui.qt import uic
uipath = path.dirname(__file__) uipath = path.dirname(__file__)

View File

@ -21,11 +21,13 @@
# #
# ***************************************************************************** # *****************************************************************************
from secop.datatypes import * from __future__ import print_function
from PyQt4.QtGui import QDialog, QPushButton, QLabel, QApplication, QLineEdit,\ from secop.datatypes import * # pylint: disable=unused-wildcard-import,wildcard-import
QGroupBox, QSpinBox, QDoubleSpinBox, QComboBox, QCheckBox, QRadioButton, \
QVBoxLayout, QGridLayout, QScrollArea, QFrame from secop.gui.qt import QDialog, QLabel, QLineEdit,\
QGroupBox, QSpinBox, QDoubleSpinBox, QComboBox, QCheckBox, \
QVBoxLayout, QGridLayout, QFrame
from secop.gui.util import loadUi from secop.gui.util import loadUi
@ -48,8 +50,8 @@ class StringWidget(QLineEdit):
class BlobWidget(StringWidget): class BlobWidget(StringWidget):
# XXX: make an editable hex-table ? # XXX: make an editable hex-table ?
pass pass
# or derive from widget and switch between combobox and radiobuttons? # or derive from widget and switch between combobox and radiobuttons?
class EnumWidget(QComboBox): class EnumWidget(QComboBox):
@ -126,7 +128,7 @@ class TupleWidget(QFrame):
super(TupleWidget, self).__init__(parent) super(TupleWidget, self).__init__(parent)
self.datatypes = datatype.subtypes self.datatypes = datatype.subtypes
self.layout = QVBoxLayout() self.layout = QVBoxLayout()
self.subwidgets = [] self.subwidgets = []
for t in self.datatypes: for t in self.datatypes:
@ -142,20 +144,20 @@ class TupleWidget(QFrame):
return [v.validate(w.get_value()) for w,v in zip(self.subwidgets, self.datatypes)] return [v.validate(w.get_value()) for w,v in zip(self.subwidgets, self.datatypes)]
def set_value(self, value): def set_value(self, value):
for w, v in zip(self.subwidgets, value): for w, _ in zip(self.subwidgets, value):
w.set_value(value) w.set_value(value)
class StructWidget(QGroupBox): class StructWidget(QGroupBox):
def __init__(self, datatype, readonly=False, parent=None): def __init__(self, datatype, readonly=False, parent=None):
super(StructWidget, self).__init__(parent) super(StructWidget, self).__init__(parent)
self.layout = QGridLayout() self.layout = QGridLayout()
self.subwidgets = {} self.subwidgets = {}
self.datatypes = [] self.datatypes = []
self._labels = [] self._labels = []
for idx, name in enumerate(sorted(datatype.named_subtypes)): for idx, name in enumerate(sorted(datatype.named_subtypes)):
dt = datatype.named_subtypes[name] dt = datatype.named_subtypes[name]
w = get_widget(dt, readonly=readonly, parent=self) w = get_widget(dt, readonly=readonly, parent=self)
l = QLabel(name) l = QLabel(name)
self.layout.addWidget(l, idx, 0) self.layout.addWidget(l, idx, 0)
@ -178,15 +180,15 @@ class StructWidget(QGroupBox):
w, dt = entry w, dt = entry
w.set_value(dt.validate(v)) w.set_value(dt.validate(v))
class ArrayWidget(QGroupBox): class ArrayWidget(QGroupBox):
def __init__(self, datatype, readonly=False, parent=None): def __init__(self, datatype, readonly=False, parent=None):
super(ArrayWidget, self).__init__(parent) super(ArrayWidget, self).__init__(parent)
self.datatype = datatype.subtype self.datatype = datatype.subtype
self.layout = QVBoxLayout() self.layout = QVBoxLayout()
self.subwidgets = [] self.subwidgets = []
for i in range(datatype.maxsize): for _ in range(datatype.maxsize):
w = get_widget(self.datatype, readonly=readonly, parent=self) w = get_widget(self.datatype, readonly=readonly, parent=self)
self.layout.addWidget(w) self.layout.addWidget(w)
self.subwidgets.append(w) self.subwidgets.append(w)
@ -199,7 +201,7 @@ class ArrayWidget(QGroupBox):
for w, v in zip(self.subwidgets, values): for w, v in zip(self.subwidgets, values):
w.set_value(v) w.set_value(v)
def get_widget(datatype, readonly=False, parent=None): def get_widget(datatype, readonly=False, parent=None):
return {FloatRange: FloatWidget, return {FloatRange: FloatWidget,
@ -221,32 +223,15 @@ class msg(QDialog):
print(dir(self)) print(dir(self))
self.setWindowTitle('Please enter the arguments for calling command "blubb()"') self.setWindowTitle('Please enter the arguments for calling command "blubb()"')
row = 0 row = 0
# self.gridLayout.addWidget(QLabel('String'), row, 0); self.gridLayout.addWidget(StringWidget(StringType()), row, 1); row += 1
# self.gridLayout.addWidget(QLabel('Blob'), row, 0); self.gridLayout.addWidget(BlobWidget(BLOBType()), row, 1); row += 1
# self.gridLayout.addWidget(QLabel('Enum'), row, 0); self.gridLayout.addWidget(EnumWidget(EnumType(a=1,b=9)), row, 1); row += 1
# self.gridLayout.addWidget(QLabel('Bool'), row, 0); self.gridLayout.addWidget(BoolWidget(BoolType()), row, 1); row += 1
# self.gridLayout.addWidget(QLabel('int'), row, 0); self.gridLayout.addWidget(IntWidget(IntRange(0,9)), row, 1); row += 1
# self.gridLayout.addWidget(QLabel('float'), row, 0); self.gridLayout.addWidget(FloatWidget(FloatRange(-9,9)), row, 1); row += 1
#self.gridLayout.addWidget(QLabel('tuple'), row, 0);
#dt = TupleOf(BoolType(), EnumType(a=2,b=3))
#w = TupleWidget(dt)
#self.gridLayout.addWidget(w, row, 1)
#row+=1
#self.gridLayout.addWidget(QLabel('array'), row, 0); self.gridLayout.addWidget(QLabel('struct'), row, 0)
#dt = ArrayOf(IntRange(0,10), 10)
#w = ArrayWidget(dt)
#self.gridLayout.addWidget(w, row, 1)
#row+=1
self.gridLayout.addWidget(QLabel('struct'), row, 0);
dt = StructOf(i=IntRange(0,10), f=FloatRange(), b=BoolType()) dt = StructOf(i=IntRange(0,10), f=FloatRange(), b=BoolType())
w = StructWidget(dt) w = StructWidget(dt)
self.gridLayout.addWidget(w, row, 1) self.gridLayout.addWidget(w, row, 1)
row+=1 row+=1
self.gridLayout.addWidget(QLabel('stuff'), row, 0, 1, 0); row += 1 # at pos (0,0) span 2 cols, 1 row self.gridLayout.addWidget(QLabel('stuff'), row, 0, 1, 0)
row += 1 # at pos (0,0) span 2 cols, 1 row
self.gridLayout.setRowStretch(row, 1) self.gridLayout.setRowStretch(row, 1)
self.setModal(True) self.setModal(True)
@ -261,4 +246,3 @@ class msg(QDialog):
def done(self, how): def done(self, how):
print('done(%r)' % how) print('done(%r)' % how)
return super(msg, self).done(how) return super(msg, self).done(how)