TableWidget updates:
- Made numerically sortable - Added setEditable method - Added example
This commit is contained in:
parent
916face815
commit
db5c303fad
34
examples/TableWidget.py
Normal file
34
examples/TableWidget.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Simple demonstration of TableWidget, which is an extension of QTableWidget
|
||||||
|
that automatically displays a variety of tabluar data formats.
|
||||||
|
"""
|
||||||
|
import initExample ## Add path to library (just for examples; you do not need this)
|
||||||
|
|
||||||
|
import pyqtgraph as pg
|
||||||
|
from pyqtgraph.Qt import QtCore, QtGui
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
app = QtGui.QApplication([])
|
||||||
|
|
||||||
|
w = pg.TableWidget()
|
||||||
|
w.show()
|
||||||
|
w.resize(500,500)
|
||||||
|
w.setWindowTitle('pyqtgraph example: TableWidget')
|
||||||
|
|
||||||
|
|
||||||
|
data = np.array([
|
||||||
|
(1, 1.6, 'x'),
|
||||||
|
(3, 5.4, 'y'),
|
||||||
|
(8, 12.5, 'z'),
|
||||||
|
(443, 1e-12, 'w'),
|
||||||
|
], dtype=[('Column 1', int), ('Column 2', float), ('Column 3', object)])
|
||||||
|
|
||||||
|
w.setData(data)
|
||||||
|
|
||||||
|
|
||||||
|
## Start Qt event loop unless running in interactive mode or using pyside.
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||||
|
QtGui.QApplication.instance().exec_()
|
@ -64,7 +64,7 @@ examples = OrderedDict([
|
|||||||
('TreeWidget', 'TreeWidget.py'),
|
('TreeWidget', 'TreeWidget.py'),
|
||||||
('DataTreeWidget', 'DataTreeWidget.py'),
|
('DataTreeWidget', 'DataTreeWidget.py'),
|
||||||
('GradientWidget', 'GradientWidget.py'),
|
('GradientWidget', 'GradientWidget.py'),
|
||||||
#('TableWidget', '../widgets/TableWidget.py'),
|
('TableWidget', 'TableWidget.py'),
|
||||||
('ColorButton', 'ColorButton.py'),
|
('ColorButton', 'ColorButton.py'),
|
||||||
#('CheckTable', '../widgets/CheckTable.py'),
|
#('CheckTable', '../widgets/CheckTable.py'),
|
||||||
#('VerticalLabel', '../widgets/VerticalLabel.py'),
|
#('VerticalLabel', '../widgets/VerticalLabel.py'),
|
||||||
|
@ -12,23 +12,20 @@ except ImportError:
|
|||||||
__all__ = ['TableWidget']
|
__all__ = ['TableWidget']
|
||||||
class TableWidget(QtGui.QTableWidget):
|
class TableWidget(QtGui.QTableWidget):
|
||||||
"""Extends QTableWidget with some useful functions for automatic data handling
|
"""Extends QTableWidget with some useful functions for automatic data handling
|
||||||
and copy / export context menu. Can automatically format and display:
|
and copy / export context menu. Can automatically format and display a variety
|
||||||
|
of data types (see :func:`setData() <pyqtgraph.TableWidget.setData>` for more
|
||||||
- numpy arrays
|
information.
|
||||||
- numpy record arrays
|
|
||||||
- metaarrays
|
|
||||||
- list-of-lists [[1,2,3], [4,5,6]]
|
|
||||||
- dict-of-lists {'x': [1,2,3], 'y': [4,5,6]}
|
|
||||||
- list-of-dicts [{'x': 1, 'y': 4}, {'x': 2, 'y': 5}, ...]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args, **kwds):
|
||||||
QtGui.QTableWidget.__init__(self, *args)
|
QtGui.QTableWidget.__init__(self, *args)
|
||||||
self.setVerticalScrollMode(self.ScrollPerPixel)
|
self.setVerticalScrollMode(self.ScrollPerPixel)
|
||||||
self.setSelectionMode(QtGui.QAbstractItemView.ContiguousSelection)
|
self.setSelectionMode(QtGui.QAbstractItemView.ContiguousSelection)
|
||||||
self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
|
||||||
self.setSortingEnabled(True)
|
self.setSortingEnabled(True)
|
||||||
self.clear()
|
self.clear()
|
||||||
|
editable = kwds.get('editable', False)
|
||||||
|
self.setEditable(editable)
|
||||||
self.contextMenu = QtGui.QMenu()
|
self.contextMenu = QtGui.QMenu()
|
||||||
self.contextMenu.addAction('Copy Selection').triggered.connect(self.copySel)
|
self.contextMenu.addAction('Copy Selection').triggered.connect(self.copySel)
|
||||||
self.contextMenu.addAction('Copy All').triggered.connect(self.copyAll)
|
self.contextMenu.addAction('Copy All').triggered.connect(self.copyAll)
|
||||||
@ -36,6 +33,7 @@ class TableWidget(QtGui.QTableWidget):
|
|||||||
self.contextMenu.addAction('Save All').triggered.connect(self.saveAll)
|
self.contextMenu.addAction('Save All').triggered.connect(self.saveAll)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
"""Clear all contents from the table."""
|
||||||
QtGui.QTableWidget.clear(self)
|
QtGui.QTableWidget.clear(self)
|
||||||
self.verticalHeadersSet = False
|
self.verticalHeadersSet = False
|
||||||
self.horizontalHeadersSet = False
|
self.horizontalHeadersSet = False
|
||||||
@ -44,6 +42,16 @@ class TableWidget(QtGui.QTableWidget):
|
|||||||
self.setColumnCount(0)
|
self.setColumnCount(0)
|
||||||
|
|
||||||
def setData(self, data):
|
def setData(self, data):
|
||||||
|
"""Set the data displayed in the table.
|
||||||
|
Allowed formats are:
|
||||||
|
|
||||||
|
* numpy arrays
|
||||||
|
* numpy record arrays
|
||||||
|
* metaarrays
|
||||||
|
* list-of-lists [[1,2,3], [4,5,6]]
|
||||||
|
* dict-of-lists {'x': [1,2,3], 'y': [4,5,6]}
|
||||||
|
* list-of-dicts [{'x': 1, 'y': 4}, {'x': 2, 'y': 5}, ...]
|
||||||
|
"""
|
||||||
self.clear()
|
self.clear()
|
||||||
self.appendData(data)
|
self.appendData(data)
|
||||||
self.resizeColumnsToContents()
|
self.resizeColumnsToContents()
|
||||||
@ -84,10 +92,15 @@ class TableWidget(QtGui.QTableWidget):
|
|||||||
for row in it0:
|
for row in it0:
|
||||||
self.setRow(i, [x for x in fn1(row)])
|
self.setRow(i, [x for x in fn1(row)])
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
def setEditable(self, editable=True):
|
||||||
|
self.editable = editable
|
||||||
|
for item in self.items:
|
||||||
|
item.setEditable(editable)
|
||||||
|
|
||||||
def iteratorFn(self, data):
|
def iteratorFn(self, data):
|
||||||
"""Return 1) a function that will provide an iterator for data and 2) a list of header strings"""
|
## Return 1) a function that will provide an iterator for data and 2) a list of header strings
|
||||||
if isinstance(data, list):
|
if isinstance(data, list) or isinstance(data, tuple):
|
||||||
return lambda d: d.__iter__(), None
|
return lambda d: d.__iter__(), None
|
||||||
elif isinstance(data, dict):
|
elif isinstance(data, dict):
|
||||||
return lambda d: iter(d.values()), list(map(str, data.keys()))
|
return lambda d: iter(d.values()), list(map(str, data.keys()))
|
||||||
@ -130,17 +143,10 @@ class TableWidget(QtGui.QTableWidget):
|
|||||||
def setRow(self, row, vals):
|
def setRow(self, row, vals):
|
||||||
if row > self.rowCount() - 1:
|
if row > self.rowCount() - 1:
|
||||||
self.setRowCount(row + 1)
|
self.setRowCount(row + 1)
|
||||||
for col in range(self.columnCount()):
|
for col in range(len(vals)):
|
||||||
val = vals[col]
|
val = vals[col]
|
||||||
if isinstance(val, float) or isinstance(val, np.floating):
|
item = TableWidgetItem(val)
|
||||||
s = "%0.3g" % val
|
item.setEditable(self.editable)
|
||||||
else:
|
|
||||||
s = str(val)
|
|
||||||
item = QtGui.QTableWidgetItem(s)
|
|
||||||
item.value = val
|
|
||||||
# by default this is enabled, selectable & editable, but
|
|
||||||
# we don't want editable
|
|
||||||
item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEnabled)
|
|
||||||
self.items.append(item)
|
self.items.append(item)
|
||||||
self.setItem(row, col, item)
|
self.setItem(row, col, item)
|
||||||
|
|
||||||
@ -228,6 +234,28 @@ class TableWidget(QtGui.QTableWidget):
|
|||||||
else:
|
else:
|
||||||
ev.ignore()
|
ev.ignore()
|
||||||
|
|
||||||
|
class TableWidgetItem(QtGui.QTableWidgetItem):
|
||||||
|
def __init__(self, val):
|
||||||
|
if isinstance(val, float) or isinstance(val, np.floating):
|
||||||
|
s = "%0.3g" % val
|
||||||
|
else:
|
||||||
|
s = str(val)
|
||||||
|
QtGui.QTableWidgetItem.__init__(self, s)
|
||||||
|
self.value = val
|
||||||
|
flags = QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
|
||||||
|
self.setFlags(flags)
|
||||||
|
|
||||||
|
def setEditable(self, editable):
|
||||||
|
if editable:
|
||||||
|
self.setFlags(self.flags() | QtCore.Qt.ItemIsEditable)
|
||||||
|
else:
|
||||||
|
self.setFlags(self.flags() & ~QtCore.Qt.ItemIsEditable)
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
if hasattr(other, 'value'):
|
||||||
|
return self.value < other.value
|
||||||
|
else:
|
||||||
|
return self.text() < other.text()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
Reference in New Issue
Block a user