# HG changeset patch # User Windel Bouwman # Date 1357234409 -3600 # Node ID ad14c7c5258984d42945f15f0cb64b746b88d480 # Parent 8267ba1dbce3bcb88a093f8e57cfa53d9d0fc0b7 Created qt property viewer diff -r 8267ba1dbce3 -r ad14c7c52589 python/hexviewer.py --- a/python/hexviewer.py Tue Jan 01 17:17:44 2013 +0100 +++ b/python/hexviewer.py Thu Jan 03 18:33:29 2013 +0100 @@ -2,6 +2,7 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * +from qtpropertyviewer import QtPropertyViewer import sys import hexfile @@ -77,11 +78,17 @@ filename = QFileDialog.getOpenFileName(self, "Open hex file...", "*.hex", "Intel hexfiles (*.hex)") if filename: h = hexfile.HexFile(filename) + @pyqtProperty(str) + def leetValue(self): + return '1337' if __name__ == '__main__': app = QApplication(sys.argv) bv = BinViewMain() bv.show() bv.bv.setHexFile(hexfile.HexFile('audio.hex')) + qpv = QtPropertyViewer() + qpv.propertyModel.InspectedWidget = bv + qpv.show() app.exec_() diff -r 8267ba1dbce3 -r ad14c7c52589 python/qtpropertyviewer.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/qtpropertyviewer.py Thu Jan 03 18:33:29 2013 +0100 @@ -0,0 +1,103 @@ +from PyQt4.QtCore import * +from PyQt4.QtGui import * +import sys + +class QtPropertyModel(QAbstractTableModel): + def __init__(self): + super().__init__() + self.InspectedWidget = None + def getInspectedWidget(self): + return self.inspectedWidget + def setInspectedWidget(self, w): + self.inspectedWidget = w + if isinstance(self.inspectedWidget, QObject): + mo = self.inspectedWidget.metaObject() + self.metaprops = [mo.property(i) for i in range(mo.propertyCount())] + self.metaprops = sorted(self.metaprops, key=lambda mp: mp.name()) + else: + self.metaprops = [] + self.modelReset.emit() + InspectedWidget = property(getInspectedWidget, setInspectedWidget) + def rowCount(self, parent): + return len(self.metaprops) + def columnCount(self, parent): + return 2 + def headerData(self, section, orientation, role): + if orientation == Qt.Horizontal and role == Qt.DisplayRole: + if section == 0: + return 'Property' + elif section == 1: + return 'Value' + def data(self, index, role): + if index.isValid(): + row = index.row() + col = index.column() + metaprop = self.metaprops[row] + if role == Qt.DisplayRole: + propname = metaprop.name() + if col == 0: + return propname + elif col == 1: + if metaprop.isReadable(): + propval = metaprop.read(self.inspectedWidget) + return propval + return 'NOT READABLE' + return '{0}, {1}'.format(row, col) + elif role == Qt.BackgroundRole: + if col == 1: + if metaprop.isWritable(): + return QBrush(Qt.green) + else: + return QBrush(Qt.red) + elif role == Qt.CheckStateRole: + if col == 1: + val = metaprop.read(self.inspectedWidget) + if type(val) is bool: + val = Qt.Checked if val else Qt.Unchecked + return val + + def flags(self, index): + if index.isValid(): + row = index.row() + col = index.column() + metaprop = self.metaprops[row] + if col == 1 and metaprop.isWritable(): + val = metaprop.read(self.inspectedWidget) + if type(val) == bool: + return super().flags(index) | Qt.ItemIsEditable | Qt.ItemIsUserCheckable + else: + return super().flags(index) | Qt.ItemIsEditable + else: + return super().flags(index) + def setData(self, index, value, role): + if index.isValid(): + row = index.row() + col = index.column() + metaprop = self.metaprops[row] + if role == Qt.EditRole: + metaprop.write(self.inspectedWidget, value) + return True + elif role == Qt.CheckStateRole: + value = True if value == Qt.Checked else False + metaprop.write(self.inspectedWidget, value) + return True + else: + print('unknown role:', role) + return False + return False + +class QtPropertyViewer(QWidget): + """ + The binviewer consists of a hex view, a ascii view + and perhaps others.. + """ + def __init__(self): + super().__init__() + tableView = QTableView() + l = QVBoxLayout(self) + l.addWidget(tableView) + header = tableView.horizontalHeader() + header.setResizeMode(QHeaderView.ResizeToContents) + self.propertyModel = QtPropertyModel() + tableView.setModel(self.propertyModel) +