| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | __title__ = "FreeCAD table view widget to visualize vtkTable" |
| | __author__ = "Stefan Tröger" |
| | __url__ = "https://www.freecad.org" |
| |
|
| | |
| | |
| | |
| |
|
| | from PySide import QtGui |
| | from PySide import QtCore |
| |
|
| | import FreeCAD |
| | import FreeCADGui |
| |
|
| | from vtkmodules.vtkIOCore import vtkDelimitedTextWriter |
| |
|
| | translate = FreeCAD.Qt.translate |
| |
|
| |
|
| | class VtkTableModel(QtCore.QAbstractTableModel): |
| | |
| | |
| | |
| | |
| |
|
| | def __init__(self, header_names=None): |
| | super().__init__() |
| | self._table = None |
| | if header_names: |
| | self._header = header_names |
| | else: |
| | self._header = {} |
| |
|
| | def setTable(self, table, header_names=None): |
| | self.beginResetModel() |
| | self._table = table |
| | if header_names: |
| | self._header = header_names |
| | self.endResetModel() |
| |
|
| | def rowCount(self, index): |
| |
|
| | if not self._table: |
| | return 0 |
| |
|
| | return self._table.GetNumberOfRows() |
| |
|
| | def columnCount(self, index): |
| |
|
| | if not self._table: |
| | return 0 |
| |
|
| | return self._table.GetNumberOfColumns() |
| |
|
| | def data(self, index, role): |
| |
|
| | if not self._table: |
| | return None |
| |
|
| | if role == QtCore.Qt.DisplayRole: |
| | col = self._table.GetColumn(index.column()) |
| | return col.GetTuple(index.row())[0] |
| |
|
| | return None |
| |
|
| | def headerData(self, section, orientation, role): |
| |
|
| | if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: |
| | if section in self._header: |
| | return self._header[section] |
| |
|
| | name = self._table.GetColumnName(section) |
| | if name in self._header: |
| | return self._header[name] |
| |
|
| | return name |
| |
|
| | if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole: |
| | return section |
| |
|
| | return None |
| |
|
| | def getTable(self): |
| | return self._table |
| |
|
| |
|
| | class VtkTableSummaryModel(QtCore.QAbstractTableModel): |
| | |
| | |
| |
|
| | def __init__(self): |
| | super().__init__() |
| | self._table = None |
| |
|
| | def setTable(self, table): |
| | self.beginResetModel() |
| | self._table = table |
| | self.endResetModel() |
| |
|
| | def rowCount(self, index): |
| |
|
| | if not self._table: |
| | return 0 |
| |
|
| | return self._table.GetNumberOfColumns() |
| |
|
| | def columnCount(self, index): |
| | return 2 |
| |
|
| | def data(self, index, role): |
| |
|
| | if not self._table: |
| | return None |
| |
|
| | if role == QtCore.Qt.DisplayRole: |
| | col = self._table.GetColumn(index.row()) |
| | range = col.GetRange() |
| | return range[index.column()] |
| |
|
| | return None |
| |
|
| | def headerData(self, section, orientation, role): |
| |
|
| | if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: |
| | return ["Min", "Max"][section] |
| |
|
| | if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole: |
| | return self._table.GetColumnName(section) |
| |
|
| | return None |
| |
|
| | def getTable(self): |
| | return self._table |
| |
|
| |
|
| | class VtkTableView(QtGui.QWidget): |
| |
|
| | def __init__(self, model): |
| | super().__init__() |
| |
|
| | self.model = model |
| |
|
| | layout = QtGui.QVBoxLayout() |
| | layout.setContentsMargins(0, 0, 0, 0) |
| | layout.setSpacing(0) |
| |
|
| | |
| | self.toolbar = QtGui.QToolBar() |
| | csv_action = QtGui.QAction(self) |
| | csv_action.triggered.connect(self.exportCsv) |
| | csv_action.setIcon(FreeCADGui.getIcon("Std_Export")) |
| | csv_action.setToolTip(translate("FEM", "Export to CSV")) |
| | self.toolbar.addAction(csv_action) |
| |
|
| | copy_action = QtGui.QAction(self) |
| | copy_action.triggered.connect(self.copyToClipboard) |
| | copy_action.setIcon(FreeCADGui.getIcon("edit-copy")) |
| | shortcut = QtGui.QKeySequence(QtGui.QKeySequence.Copy) |
| | copy_action.setToolTip( |
| | translate("FEM", "Copy selection to clipboard ({})".format(shortcut.toString())) |
| | ) |
| | copy_action.setShortcut(shortcut) |
| | self.toolbar.addAction(copy_action) |
| |
|
| | layout.addWidget(self.toolbar) |
| |
|
| | |
| | self.table_view = QtGui.QTableView() |
| | self.table_view.setModel(model) |
| | self.model.modelReset.connect(self.modelReset) |
| |
|
| | |
| | header = self.table_view.horizontalHeader() |
| | header.setResizeContentsPrecision(10) |
| | self.table_view.resizeColumnsToContents() |
| |
|
| | layout.addWidget(self.table_view) |
| | self.setLayout(layout) |
| |
|
| | @QtCore.Slot() |
| | def modelReset(self): |
| | |
| | |
| | self.table_view.resizeColumnsToContents() |
| |
|
| | @QtCore.Slot(bool) |
| | def exportCsv(self, state): |
| |
|
| | file_path, filter = QtGui.QFileDialog.getSaveFileName( |
| | None, translate("FEM", "Save as csv file"), "", "CSV (*.csv)" |
| | ) |
| | if not file_path: |
| | FreeCAD.Console.PrintMessage( |
| | translate("FEM", "CSV file export aborted: no filename selected") |
| | ) |
| | return |
| |
|
| | writer = vtkDelimitedTextWriter() |
| | writer.SetFileName(file_path) |
| | writer.SetInputData(self.model.getTable()) |
| | writer.Write() |
| |
|
| | @QtCore.Slot() |
| | def copyToClipboard(self): |
| |
|
| | sel_model = self.table_view.selectionModel() |
| | selection = sel_model.selectedIndexes() |
| |
|
| | if len(selection) < 1: |
| | return |
| |
|
| | copy_table = "" |
| | previous = selection.pop(0) |
| | for current in selection: |
| |
|
| | data = self.model.data(previous, QtCore.Qt.DisplayRole) |
| | copy_table += str(data) |
| |
|
| | if current.row() != previous.row(): |
| | copy_table += "\n" |
| | else: |
| | copy_table += "\t" |
| |
|
| | previous = current |
| |
|
| | copy_table += str(self.model.data(selection[-1], QtCore.Qt.DisplayRole)) |
| | copy_table += "\n" |
| |
|
| | clipboard = QtGui.QApplication.instance().clipboard() |
| | clipboard.setText(copy_table) |
| |
|