Source code for taurus.qt.qtgui.table.taurusdevicepropertytable

#!/usr/bin/env python

# ###########################################################################
#
# This file is part of Taurus
#
# http://taurus-scada.org
#
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
#
# Taurus is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Taurus 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Taurus.  If not, see <http://www.gnu.org/licenses/>.
#
# ###########################################################################

"""
taurusdevicepropertytable.py:
"""

# todo: tango-centric

from taurus.external.qt import Qt, QtCore, QtGui
from taurus.qt.qtgui.base import TaurusBaseWidget
from taurus.core.taurusdevice import TaurusDevice


[docs]class TaurusPropTable(QtGui.QTableWidget, TaurusBaseWidget): """ This widget will show a list of properties of device and the list of values. """ # TODO add a frame for Add, Delete and Refresh buttons! # TODO This widget is Tango-centric def __init__(self, parent=None, designMode=False): try: name = "TaurusPropTable" self._useParentModel = True self._localModel = "" self.call__init__wo_kw(QtGui.QTableWidget, parent) self.call__init__(TaurusBaseWidget, name, designMode=designMode) self.setObjectName(name) self.defineStyle() self.db = None except Exception: self.traceback() # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ # TaurusBaseWidget over writing methods # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
[docs] def setModel(self, model, **kwargs): TaurusBaseWidget.setModel(self, model) # Update the table modelObj = self.getModelObj() if modelObj is None: dev_name = None self.db = None else: validator = modelObj.getNameValidator() groups = validator.getUriGroups(modelObj.getFullName()) dev_name = groups["devname"] # ----------------------------------------------------------------- # Workaround for bug-256 # (use next line instead of the other one when bug-256 is fixed) # self.db = modelObj.getParentObj() # use this instead self.db = modelObj.factory().getAuthority(groups["authority"]) # ----------------------------------------------------------------- self.setTable(dev_name)
[docs] def sizeHint(self): return QtGui.QTableWidget.sizeHint(self)
[docs] def minimumSizeHint(self): return QtGui.QTableWidget.minimumSizeHint(self)
[docs] def getModelClass(self, **kwargs): return TaurusDevice
[docs] @classmethod def getQtDesignerPluginInfo(cls): ret = TaurusBaseWidget.getQtDesignerPluginInfo() ret["module"] = "taurus.qt.qtgui.table" ret["group"] = "Taurus Views" ret["icon"] = "designer:table.png" return ret
# -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ # QT properties # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ model = QtCore.pyqtProperty( "QString", TaurusBaseWidget.getModel, setModel, TaurusBaseWidget.resetModel, ) #: (deprecated)) useParentModel = QtCore.pyqtProperty( "bool", TaurusBaseWidget.getUseParentModel, TaurusBaseWidget.setUseParentModel, TaurusBaseWidget.resetUseParentModel, ) # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ # My methods # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
[docs] @QtCore.pyqtSlot("QString") def setTable(self, dev_name): """ Fills the table with the names of properties and their values for the given device. """ if dev_name is None: return # TODO: the table should be cleaned elif self.db is None: self.warning("Model must be set before calling setTable") return try: self.cellChanged.disconnect(self.valueChanged) except Exception: pass dev_name = str(dev_name) self.list_prop = list(self.db.get_device_property_list(dev_name, "*")) self.setRowCount(len(self.list_prop)) for i in range(0, len(self.list_prop)): elem = self.list_prop[i] self.setText(elem, i, 0) self.dictionary = self.db.get_device_property( dev_name, self.list_prop ) self.debug( "Getting %s properties: %s -> %s", dev_name, self.list_prop, self.dictionary, ) value = self.dictionary[elem] self.debug( "TaurusPropsTable: property %s is type %s", elem, type(value) ) USE_TABLES = False if USE_TABLES: self.setPropertyValue(value, i, 1) else: if not isinstance(value, str): # not something like an string # adding new lines in between elements in the list value = "\n".join(str(v) for v in value) self.setText(str(value), i, 1) self.updateStyle() self.dev_name = dev_name self.setWindowTitle("%s Properties" % dev_name) self.resizeColumnsToContents() self.resizeRowsToContents()
[docs] def defineStyle(self): """Defines the initial style for the widget""" self.setWindowTitle("Properties") self.setColumnCount(2) self.setRowCount(0) self.setGeometry(QtCore.QRect(0, 0, 400, 500)) self.setColumnWidth(0, 124) self.setColumnWidth(1, 254) headerItem = QtGui.QTableWidgetItem() headerItem.setText( QtGui.QApplication.translate( "PLCTabWidget", "Property Name", None, QtGui.QApplication.UnicodeUTF8, ) ) self.setHorizontalHeaderItem(0, headerItem) headerItem1 = QtGui.QTableWidgetItem() headerItem1.setText( QtGui.QApplication.translate( "PLCTabWidget", "Value", None, QtGui.QApplication.UnicodeUTF8 ) ) self.setHorizontalHeaderItem(1, headerItem1) hh = self.horizontalHeader() if hh.length() > 0: hh.setSectionResizeMode(hh.ResizeToContents)
[docs] def updateStyle(self): self.resizeRowsToContents() hh = self.horizontalHeader() if hh.length() > 0: hh.setSectionResizeMode(hh.ResizeToContents)
# self.resizeColumnsToContents()
[docs] def contextMenuEvent(self, event): """This function is called when right clicking on qwt plot area. A pop up menu will be shown with the available options. """ self.info("TaurusPropTable.contextMenuEvent()") menu = Qt.QMenu(self) configDialogAction = menu.addAction("Add new property") configDialogAction.triggered.connect(self.addProperty) configDialogAction = menu.addAction("Delete property") configDialogAction.triggered.connect(self.deleteProperty) configDialogAction = menu.addAction("Edit property") configDialogAction.triggered.connect(self.editProperty) menu.addSeparator() menu.exec_(event.globalPos()) del menu
[docs] def setText(self, value, i=None, j=None): item = QtGui.QTableWidgetItem() item.setFlags(Qt.Qt.ItemIsEnabled) item.setText( QtGui.QApplication.translate( "PLCTabWidget", value, None, QtGui.QApplication.UnicodeUTF8 ) ) if i is not None and j is not None: self.setItem(i, j, item)
# TODO: the info does not change with the events.
[docs] def valueDoubleClicked(self, x, y): self.info("TaurusPropTable.valueDoubleClicked(%s,%s)" % (x, y)) # opens a dialog for multiline edition self.editProperty()
# -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ # @name Property Edition # @{ # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
[docs] def addProperty(self): text, ok = QtGui.QInputDialog.getText( self, "New Property", "Property name:" ) if ok: text1 = str(text) new_prop_name = str(text1) new_prop_value = "0" dict1 = {new_prop_name: [new_prop_value]} self.db.put_device_property(self.dev_name, dict1) self.setTable(self.dev_name)
[docs] def deleteProperty(self): row = self.currentRow() prop_name = self.item(row, 0).text() list = [str(prop_name)] yes = QtGui.QMessageBox.Ok no = QtGui.QMessageBox.Cancel result = QtGui.QMessageBox.question( self, "Removing property", "Would you like to delete property '" + prop_name + "' ?", yes, no, ) if result == yes: self.db.delete_device_property(self.dev_name, list) self.setTable(self.dev_name)
[docs] def editProperty(self): row = self.currentRow() col = self.currentColumn() item1 = QtGui.QTableWidgetItem() item1 = self.item(row, 0) prop_name = item1.text() prop_name = str(prop_name) self.prop_name2 = prop_name self.info("TaurusPropsTable.editProperty(%s)" % prop_name) item2 = QtGui.QTableWidgetItem() item2 = self.item(row, 1) prop_value = item2.text() prop_value = str(prop_value) if col == 0: new_text, ok = QtGui.QInputDialog.getText( self, "Rename", "Write new name of property:" ) if ok: new_text = str(new_text) new_text = str(new_text) list = [prop_name] dict = {new_text: [prop_value]} # usuwanie musze umiescic gdzies wczesniej bo inaczej usuwam # juz zmieniana nazwe z listy property self.db.delete_device_property(self.dev_name, list) self.db.put_device_property(self.dev_name, dict) self.setTable(self.dev_name) elif col == 1: # Create the dilog to edit multiply text dialogx = EditTextDialog(self) dialogx.setText(prop_value) dialogx.exec_() ok = dialogx.getResult() # OK or Cancel if ok: new_text = ( dialogx.getNewText() ) # method of dialog to get the changed text self.setNewPropertyValue(new_text)
[docs] def setNewPropertyValue(self, new_text): new_text = str(new_text) new_text = str(new_text) values = {self.prop_name2: new_text.replace("\r", "").split("\n")} self.db.put_device_property(self.dev_name, values) self.setTable(self.dev_name) self.updateStyle()
# @} # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ # Methods for database commands # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
[docs] def get_device_property_names(self, dev_name, wildcard="*"): return self.db.get_device_property_list(dev_name, wildcard)
[docs] def put_device_property(self, dev_name, dict): return self.db.put_device_property(dev_name, dict)
# -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ # @name DEPRECATED METHODS # @{ # -~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
[docs] def valueChanged(self): """@deprecated valueChanged THIS DOES NOTHING!""" row = self.currentRow() # item = QtGui.QTableWidgetItem() item = self.item(row, 0) prop_name = item.text() prop_name = str(prop_name) # item_2 = QtGui.QTableWidgetItem() item_2 = self.item(row, 1) prop_value = item_2.text() prop_value = str(prop_value) dict = {prop_name: [prop_value]} list = [self.prop_name] self.db.delete_device_property(self.dev_name, list) self.db.put_device_property(self.dev_name, dict)
[docs] def setPropertyValue(self, value, i, j): """This method inserts a new table widget inside the cell @deprecated ... use setText() and editProperty() event call instead!!! """ if len(value) == 1 and isinstance(value[0], str): value = value[0] if isinstance(value, str): # and '\n' in value: value = value.split("\n") if False: # isinstance(value,str): item = QtGui.QTableWidgetItem() item.setText( QtGui.QApplication.translate( "PLCTabWidget", value, None, QtGui.QApplication.UnicodeUTF8 ) ) self.setItem(i, j, item) else: item = QtGui.QTableWidget(len(value), 1) item.setItemDelegate(Delegate(item)) item.horizontalHeader().hide() item.verticalHeader().hide() # item.setGridStyle(Qt.Qt.DashLine) for k, v in enumerate(value): cell = QtGui.QTableWidgetItem() cell.setText( QtGui.QApplication.translate( "PLCTabWidget", v, None, QtGui.QApplication.UnicodeUTF8 ) ) item.setItem(k, 0, cell) item.setSizePolicy( QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding, ) self.setCellWidget(i, j, item) self.resizeColumnsToContents() self.resizeRowsToContents() return
# @} class EditTextDialog(QtGui.QDialog): """This class create the dialog using to edit multiply text""" def __init__(self, parent=None): print("In EditTextDialog.__init__()") QtGui.QDialog.__init__(self, parent) self.setModal(1) self.initComponents() self.show() self.result = 0 # Signals self.buttonBox.accepted.connect(self.pressOK) self.buttonBox.rejected.connect(self.close) def initComponents(self): widgetLayout = QtGui.QVBoxLayout(self) widgetLayout.setContentsMargins(10, 10, 10, 10) self.editText = QtGui.QTextEdit() self.buttonBox = QtGui.QDialogButtonBox() self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons( QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.NoButton | QtGui.QDialogButtonBox.Ok ) widgetLayout.addWidget(self.editText) widgetLayout.addWidget(self.buttonBox) def pressOK(self): print("In EditTextDialog.pressOk()") self.new_text = self.editText.toPlainText() self.result = 1 self.close() def setText(self, text): self.editText.setText(text) self.new_text = text def getNewText(self): return self.new_text def getResult(self): return self.result class Delegate(QtGui.QItemDelegate): """Usage: table = QtGui.QTableWidget() table.setItemDelegate(Delegate(table)) """ def __init__(self, parent=None): QtGui.QItemDelegate.__init__(self, parent) def sizeHint(self, option, index): table = self.parent() widget = table.cellWidget(index.row(), index.column()) if not widget: widget = table.itemAt(index.row(), index.column()) size = widget.sizeHint() return size if __name__ == "__main__": import sys from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication( app_name="TaurusDevice property table", cmd_line_parser=None ) widget = TaurusPropTable() args = sys.argv if len(args) == 1: model = "sys/tg_test/1" else: model = str(args[1]) widget.setModel(model) widget.show() app.exec_()