TableWidget updates:

- Made numerically sortable
  - Added setEditable method
  - Added example
This commit is contained in:
Luke Campagnola 2013-03-06 06:27:24 -05:00
parent 916face815
commit db5c303fad
3 changed files with 84 additions and 22 deletions

34
examples/TableWidget.py Normal file
View 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_()

View File

@ -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'),

View File

@ -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()
@ -85,9 +93,14 @@ class TableWidget(QtGui.QTableWidget):
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__':