Module soitool.modules.module_table
Module containing a general SOI-module table.
Expand source code
"""Module containing a general SOI-module table."""
from PySide2.QtWidgets import QTableWidget, QTableWidgetItem
from PySide2 import QtGui, QtCore
from soitool.modules.module_base import (
ModuleBase,
resize_table,
get_table_size,
prepare_table_for_pdf_export,
is_event_add_row,
is_event_remove_row,
is_event_add_column,
is_event_remove_column,
)
START_ROWS = 2
START_COLUMNS = 2
class Meta(type(ModuleBase), type(QTableWidget)):
"""Used as a metaclass to enable multiple inheritance."""
class TableModule(ModuleBase, QTableWidget, metaclass=Meta):
"""Modified QTableWidget.
By default, the widget initializes as an empty START_ROWS * START_COLUMNS
table. If parameter 'data' is given, the table initializes based on the
content.
'data' is a 2D list where data[x][y] represents row x, column y.
The widget does not use more room than needed, and resizes dynamically.
Columnheaders are styled with light grey background and bold text.
It has shortcuts for adding and removing rows and columns.
Inherits from ModuleBase and QTableWidget.
ModuleBase is used as an interface, it's methods are overridden.
"""
def __init__(self, data=None):
self.type = "TableModule"
QTableWidget.__init__(self)
ModuleBase.__init__(self)
# Remove headers and scrollbars
self.horizontalHeader().hide()
self.verticalHeader().hide()
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
# Make cell-borders black for increased readability
self.setStyleSheet("QTableView { gridline-color: black; }")
# If parameter 'data' is None, start as empty table.
if data is None:
# Set number of columns and rows
self.setColumnCount(START_COLUMNS)
self.setRowCount(START_ROWS)
# Resize width and height of rows, columns and window
resize_table(self)
# Set header-items
for i in range(self.columnCount()):
self.set_header_item(i, "")
else:
self.setColumnCount(len(data[0]))
self.setRowCount(len(data))
# Set header-items
for i in range(self.columnCount()):
self.set_header_item(i, data[0][i])
# Set cell-items
for i in range(1, self.rowCount()):
for j in range(self.columnCount()):
item = QTableWidgetItem(data[i][j])
self.setItem(i, j, item)
resize_table(self)
self.cellChanged.connect(lambda: resize_table(self))
def keyPressEvent(self, event):
"""Launch actions when specific combinations of keys are pressed.
If the keys pressed are not related to a shortcut on this custom widget
the event is sent on to be handled by the superclass (for navigation
with arrow-keys for.eg.)
Parameters
----------
event : QKeyEvent
event sent by Qt for us to handle
"""
if is_event_add_column(event):
self.add_column()
elif is_event_remove_column(event):
self.remove_column()
elif is_event_add_row(event):
self.add_row()
elif is_event_remove_row(event):
self.remove_row()
else:
super(TableModule, self).keyPressEvent(event)
def set_header_item(self, column, text):
"""Insert item with header-style.
Item will always be set on header (top) row.
Parameters
----------
column : int
What column index for inserting item.
text : String
What text the item should contain.
"""
item = QTableWidgetItem(text)
item.setBackground(QtGui.QBrush(QtGui.QColor(220, 220, 220)))
item.setFont(self.headline_font)
self.setItem(0, column, item)
def add_column(self):
"""Add column to the right of selected column."""
self.insertColumn(self.currentColumn() + 1)
self.set_header_item(self.currentColumn() + 1, "")
resize_table(self)
def remove_column(self):
"""Remove selected column if two or more columns exist."""
if self.columnCount() > 1:
self.removeColumn(self.currentColumn())
resize_table(self)
def add_row(self):
"""Add row below selected row."""
self.insertRow(self.currentRow() + 1)
resize_table(self)
def remove_row(self):
"""Remove selected row if two or more rows exist (including header)."""
if self.rowCount() > 2 and self.currentRow() != 0:
self.removeRow(self.currentRow())
resize_table(self)
def get_size(self):
"""Return size of widget."""
return get_table_size(self)
def get_data(self):
"""Return list containing module data.
Returns
-------
List (2D)
list[x][y] represents value of row x, column y.
"""
content = []
for i in range(self.rowCount()):
row = []
for j in range(self.columnCount()):
item = self.item(i, j)
if item is not None:
row.append(item.text())
else:
row.append("")
content.append(row)
return content
def prepare_for_pdf_export(self):
"""Prepare for PDF-export."""
prepare_table_for_pdf_export(self)
@staticmethod
def get_user_friendly_name():
"""Get user-friendly name of module."""
return "Generisk tabell"
@staticmethod
def get_icon():
"""Get icon of module."""
return QtGui.QIcon("soitool/media/tablemodule.png")
Classes
class Meta (name, bases, namespace, **kwargs)
-
Used as a metaclass to enable multiple inheritance.
Expand source code
class Meta(type(ModuleBase), type(QTableWidget)): """Used as a metaclass to enable multiple inheritance."""
Ancestors
- abc.ABCMeta
- Shiboken.ObjectType
- builtins.type
class TableModule (data=None)
-
Modified QTableWidget.
By default, the widget initializes as an empty START_ROWS * START_COLUMNS table. If parameter 'data' is given, the table initializes based on the content. 'data' is a 2D list where data[x][y] represents row x, column y.
The widget does not use more room than needed, and resizes dynamically. Columnheaders are styled with light grey background and bold text. It has shortcuts for adding and removing rows and columns.
Inherits from ModuleBase and QTableWidget. ModuleBase is used as an interface, it's methods are overridden.
Class-variable 'type' should be set by derived class.
Expand source code
class TableModule(ModuleBase, QTableWidget, metaclass=Meta): """Modified QTableWidget. By default, the widget initializes as an empty START_ROWS * START_COLUMNS table. If parameter 'data' is given, the table initializes based on the content. 'data' is a 2D list where data[x][y] represents row x, column y. The widget does not use more room than needed, and resizes dynamically. Columnheaders are styled with light grey background and bold text. It has shortcuts for adding and removing rows and columns. Inherits from ModuleBase and QTableWidget. ModuleBase is used as an interface, it's methods are overridden. """ def __init__(self, data=None): self.type = "TableModule" QTableWidget.__init__(self) ModuleBase.__init__(self) # Remove headers and scrollbars self.horizontalHeader().hide() self.verticalHeader().hide() self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) # Make cell-borders black for increased readability self.setStyleSheet("QTableView { gridline-color: black; }") # If parameter 'data' is None, start as empty table. if data is None: # Set number of columns and rows self.setColumnCount(START_COLUMNS) self.setRowCount(START_ROWS) # Resize width and height of rows, columns and window resize_table(self) # Set header-items for i in range(self.columnCount()): self.set_header_item(i, "") else: self.setColumnCount(len(data[0])) self.setRowCount(len(data)) # Set header-items for i in range(self.columnCount()): self.set_header_item(i, data[0][i]) # Set cell-items for i in range(1, self.rowCount()): for j in range(self.columnCount()): item = QTableWidgetItem(data[i][j]) self.setItem(i, j, item) resize_table(self) self.cellChanged.connect(lambda: resize_table(self)) def keyPressEvent(self, event): """Launch actions when specific combinations of keys are pressed. If the keys pressed are not related to a shortcut on this custom widget the event is sent on to be handled by the superclass (for navigation with arrow-keys for.eg.) Parameters ---------- event : QKeyEvent event sent by Qt for us to handle """ if is_event_add_column(event): self.add_column() elif is_event_remove_column(event): self.remove_column() elif is_event_add_row(event): self.add_row() elif is_event_remove_row(event): self.remove_row() else: super(TableModule, self).keyPressEvent(event) def set_header_item(self, column, text): """Insert item with header-style. Item will always be set on header (top) row. Parameters ---------- column : int What column index for inserting item. text : String What text the item should contain. """ item = QTableWidgetItem(text) item.setBackground(QtGui.QBrush(QtGui.QColor(220, 220, 220))) item.setFont(self.headline_font) self.setItem(0, column, item) def add_column(self): """Add column to the right of selected column.""" self.insertColumn(self.currentColumn() + 1) self.set_header_item(self.currentColumn() + 1, "") resize_table(self) def remove_column(self): """Remove selected column if two or more columns exist.""" if self.columnCount() > 1: self.removeColumn(self.currentColumn()) resize_table(self) def add_row(self): """Add row below selected row.""" self.insertRow(self.currentRow() + 1) resize_table(self) def remove_row(self): """Remove selected row if two or more rows exist (including header).""" if self.rowCount() > 2 and self.currentRow() != 0: self.removeRow(self.currentRow()) resize_table(self) def get_size(self): """Return size of widget.""" return get_table_size(self) def get_data(self): """Return list containing module data. Returns ------- List (2D) list[x][y] represents value of row x, column y. """ content = [] for i in range(self.rowCount()): row = [] for j in range(self.columnCount()): item = self.item(i, j) if item is not None: row.append(item.text()) else: row.append("") content.append(row) return content def prepare_for_pdf_export(self): """Prepare for PDF-export.""" prepare_table_for_pdf_export(self) @staticmethod def get_user_friendly_name(): """Get user-friendly name of module.""" return "Generisk tabell" @staticmethod def get_icon(): """Get icon of module.""" return QtGui.QIcon("soitool/media/tablemodule.png")
Ancestors
- ModuleBase
- abc.ABC
- PySide2.QtWidgets.QTableWidget
- PySide2.QtWidgets.QTableView
- PySide2.QtWidgets.QAbstractItemView
- PySide2.QtWidgets.QAbstractScrollArea
- PySide2.QtWidgets.QFrame
- PySide2.QtWidgets.QWidget
- PySide2.QtCore.QObject
- PySide2.QtGui.QPaintDevice
- Shiboken.Object
Class variables
var staticMetaObject
Static methods
def get_icon()
-
Get icon of module.
Expand source code
@staticmethod def get_icon(): """Get icon of module.""" return QtGui.QIcon("soitool/media/tablemodule.png")
def get_user_friendly_name()
-
Get user-friendly name of module.
Expand source code
@staticmethod def get_user_friendly_name(): """Get user-friendly name of module.""" return "Generisk tabell"
Methods
def add_column(self)
-
Add column to the right of selected column.
Expand source code
def add_column(self): """Add column to the right of selected column.""" self.insertColumn(self.currentColumn() + 1) self.set_header_item(self.currentColumn() + 1, "") resize_table(self)
def add_row(self)
-
Add row below selected row.
Expand source code
def add_row(self): """Add row below selected row.""" self.insertRow(self.currentRow() + 1) resize_table(self)
def get_data(self)
-
Return list containing module data.
Returns
List
(2D
)- list[x][y] represents value of row x, column y.
Expand source code
def get_data(self): """Return list containing module data. Returns ------- List (2D) list[x][y] represents value of row x, column y. """ content = [] for i in range(self.rowCount()): row = [] for j in range(self.columnCount()): item = self.item(i, j) if item is not None: row.append(item.text()) else: row.append("") content.append(row) return content
def get_size(self)
-
Return size of widget.
Expand source code
def get_size(self): """Return size of widget.""" return get_table_size(self)
def keyPressEvent(self, event)
-
Launch actions when specific combinations of keys are pressed.
If the keys pressed are not related to a shortcut on this custom widget the event is sent on to be handled by the superclass (for navigation with arrow-keys for.eg.)
Parameters
event
:QKeyEvent
- event sent by Qt for us to handle
Expand source code
def keyPressEvent(self, event): """Launch actions when specific combinations of keys are pressed. If the keys pressed are not related to a shortcut on this custom widget the event is sent on to be handled by the superclass (for navigation with arrow-keys for.eg.) Parameters ---------- event : QKeyEvent event sent by Qt for us to handle """ if is_event_add_column(event): self.add_column() elif is_event_remove_column(event): self.remove_column() elif is_event_add_row(event): self.add_row() elif is_event_remove_row(event): self.remove_row() else: super(TableModule, self).keyPressEvent(event)
def prepare_for_pdf_export(self)
-
Prepare for PDF-export.
Expand source code
def prepare_for_pdf_export(self): """Prepare for PDF-export.""" prepare_table_for_pdf_export(self)
def remove_column(self)
-
Remove selected column if two or more columns exist.
Expand source code
def remove_column(self): """Remove selected column if two or more columns exist.""" if self.columnCount() > 1: self.removeColumn(self.currentColumn()) resize_table(self)
def remove_row(self)
-
Remove selected row if two or more rows exist (including header).
Expand source code
def remove_row(self): """Remove selected row if two or more rows exist (including header).""" if self.rowCount() > 2 and self.currentRow() != 0: self.removeRow(self.currentRow()) resize_table(self)
def set_header_item(self, column, text)
-
Insert item with header-style.
Item will always be set on header (top) row.
Parameters
column
:int
- What column index for inserting item.
text
:String
- What text the item should contain.
Expand source code
def set_header_item(self, column, text): """Insert item with header-style. Item will always be set on header (top) row. Parameters ---------- column : int What column index for inserting item. text : String What text the item should contain. """ item = QTableWidgetItem(text) item.setBackground(QtGui.QBrush(QtGui.QColor(220, 220, 220))) item.setFont(self.headline_font) self.setItem(0, column, item)