Module soitool.codebook_model_view

GUI-interface towards database-table 'CodeBook'.

Contains functionality for viewing, editing and inserting new rows in the database-table 'CodeBook'.

Expand source code
"""GUI-interface towards database-table 'CodeBook'.

Contains functionality for viewing, editing and inserting new rows
in the database-table 'CodeBook'.
"""
from PySide2.QtWidgets import QTableView
from PySide2.QtSql import QSqlDatabase, QSqlTableModel
from PySide2.QtCore import Qt
from soitool.table_view_style import (
    CODEBOOK_HEADER_FONT,
    CODEBOOK_HEADER_BACKGROUND_CSS,
)

# Name and type of database
CONNAME = "CODEBOOKDB"
DBTYPE = "QSQLITE"


class CodebookTableView(QTableView):
    """TableView with a model of the 'Codebook'-table from database.

    This modified QTableView creates a CodebookTableModel, which reads the
    Codebook-table. User can add, edit, delete and insert entries through this
    view.

    Parameters
    ----------
    database : soitool.database.Database
        Should be an instance of soitool.database.Database, and is used to
        create a QSqlDatabase from the database-file.

    Raises
    ------
    RuntimeError
        If database does not open.
    """

    def __init__(self, database):
        super().__init__()
        db = QSqlDatabase.addDatabase(DBTYPE, CONNAME)
        db.setDatabaseName(database.db_path)

        if not db.open():
            raise RuntimeError("Could not open database.")

        # Enable sorting and hide vertical header
        self.setSortingEnabled(True)
        self.verticalHeader().hide()

        # Create and set model:
        model = CodebookTableModel()
        self.setModel(model)

        self.setEditTriggers(self.DoubleClicked)

        self.set_horizontal_header_text()

        # Set style of horizontal header
        header = self.horizontalHeader()
        header.setFont(CODEBOOK_HEADER_FONT)
        header.setStyleSheet(CODEBOOK_HEADER_BACKGROUND_CSS)

        self.setFixedWidth(600)

        self.resizeColumnsToContents()

    def set_horizontal_header_text(self):
        """Set Norwegian names in horizontal header."""
        self.model().setHeaderData(0, Qt.Horizontal, "Ord/Uttrykk")
        self.model().setHeaderData(1, Qt.Horizontal, "Kategori")
        self.model().setHeaderData(2, Qt.Horizontal, "Type")
        self.model().setHeaderData(3, Qt.Horizontal, "Kode")

    def close_db_connection(self):
        """Close database-connection."""
        self.setModel(None)
        QSqlDatabase.removeDatabase(CONNAME)

    def dataChanged(self, top_left, top_right, roles):
        """Resize column-width to contents when data changes.

        All parameters are sent to super.
        """
        super().dataChanged(top_left, top_right, roles)

        self.resizeColumnsToContents()

    def keyPressEvent(self, event):
        """Delete selected row and refresh view if delete-key was pressed.

        Parameters
        ----------
        event : QKeyEvent
            Describes a key event.
        """
        if event.key() == Qt.Key_Delete:
            index = self.currentIndex().row()
            self.model().removeRows(index, 1)
            self.model().select()
        super().keyPressEvent(event)

    def setModel(self, model):
        """Resize column-width to contents when a model is set.

        Parameter is sent to super.
        """
        super().setModel(model)
        if model is not None:
            self.set_horizontal_header_text()
            self.resizeColumnsToContents()


class CodebookTableModel(QSqlTableModel):
    """Editable QSqlTableModel of database-table 'Codebook'.

    This modified QSqlTableModel writes to database when a value is changed
    in the view. All columns except 'Code' are editable.

    This class initializes by connecting to database and selecting table.
    """

    def __init__(self):
        super().__init__(None, QSqlDatabase.database(CONNAME))
        self.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.setTable("Codebook")
        self.setSort(0, Qt.AscendingOrder)
        self.select()

    def flags(self, index):
        """Add or remove correct flags for items.

        Set items in columns Word, Category & Type editable.
        Disable items in column Code, these are not editable.

        Parameters
        ----------
        index : QModelIndex
            Is used to locate data in a data model.

        Returns
        -------
        ItemFlag
            Describes the properties of an item.
        """
        flags = super().flags(index)

        # Disable items in column 'Code'
        if index.column() == 3:
            flags ^= Qt.ItemIsEnabled
        # Enable editing on items in columns 'Word', 'Category' and 'Type'
        else:
            flags |= Qt.ItemIsEditable

        return flags

    def setData(self, index, value, role):
        """Validate correct values in column 'Type'.

        Allowed values for column 'Type' are 'Liten' and 'Stor'.
        This function ensures value is correctly cased.

        Returns
        -------
            False if incorrect Type value, returns super otherwise.
        """
        # If a change is made to column 'Type'
        if index.column() == 2:
            # If correct string, replace with correctly cased str
            if value.lower() == "liten":
                value = "Liten"
            elif value.lower() == "stor":
                value = "Stor"
            else:
                return False

        return super().setData(index, value, role)

Classes

class CodebookTableModel

Editable QSqlTableModel of database-table 'Codebook'.

This modified QSqlTableModel writes to database when a value is changed in the view. All columns except 'Code' are editable.

This class initializes by connecting to database and selecting table.

Expand source code
class CodebookTableModel(QSqlTableModel):
    """Editable QSqlTableModel of database-table 'Codebook'.

    This modified QSqlTableModel writes to database when a value is changed
    in the view. All columns except 'Code' are editable.

    This class initializes by connecting to database and selecting table.
    """

    def __init__(self):
        super().__init__(None, QSqlDatabase.database(CONNAME))
        self.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.setTable("Codebook")
        self.setSort(0, Qt.AscendingOrder)
        self.select()

    def flags(self, index):
        """Add or remove correct flags for items.

        Set items in columns Word, Category & Type editable.
        Disable items in column Code, these are not editable.

        Parameters
        ----------
        index : QModelIndex
            Is used to locate data in a data model.

        Returns
        -------
        ItemFlag
            Describes the properties of an item.
        """
        flags = super().flags(index)

        # Disable items in column 'Code'
        if index.column() == 3:
            flags ^= Qt.ItemIsEnabled
        # Enable editing on items in columns 'Word', 'Category' and 'Type'
        else:
            flags |= Qt.ItemIsEditable

        return flags

    def setData(self, index, value, role):
        """Validate correct values in column 'Type'.

        Allowed values for column 'Type' are 'Liten' and 'Stor'.
        This function ensures value is correctly cased.

        Returns
        -------
            False if incorrect Type value, returns super otherwise.
        """
        # If a change is made to column 'Type'
        if index.column() == 2:
            # If correct string, replace with correctly cased str
            if value.lower() == "liten":
                value = "Liten"
            elif value.lower() == "stor":
                value = "Stor"
            else:
                return False

        return super().setData(index, value, role)

Ancestors

  • PySide2.QtSql.QSqlTableModel
  • PySide2.QtSql.QSqlQueryModel
  • PySide2.QtCore.QAbstractTableModel
  • PySide2.QtCore.QAbstractItemModel
  • PySide2.QtCore.QObject
  • Shiboken.Object

Class variables

var staticMetaObject

Methods

def flags(self, index)

Add or remove correct flags for items.

Set items in columns Word, Category & Type editable. Disable items in column Code, these are not editable.

Parameters

index : QModelIndex
Is used to locate data in a data model.

Returns

ItemFlag
Describes the properties of an item.
Expand source code
def flags(self, index):
    """Add or remove correct flags for items.

    Set items in columns Word, Category & Type editable.
    Disable items in column Code, these are not editable.

    Parameters
    ----------
    index : QModelIndex
        Is used to locate data in a data model.

    Returns
    -------
    ItemFlag
        Describes the properties of an item.
    """
    flags = super().flags(index)

    # Disable items in column 'Code'
    if index.column() == 3:
        flags ^= Qt.ItemIsEnabled
    # Enable editing on items in columns 'Word', 'Category' and 'Type'
    else:
        flags |= Qt.ItemIsEditable

    return flags
def setData(self, index, value, role)

Validate correct values in column 'Type'.

Allowed values for column 'Type' are 'Liten' and 'Stor'. This function ensures value is correctly cased.

Returns

False if incorrect Type value, returns super otherwise.
Expand source code
def setData(self, index, value, role):
    """Validate correct values in column 'Type'.

    Allowed values for column 'Type' are 'Liten' and 'Stor'.
    This function ensures value is correctly cased.

    Returns
    -------
        False if incorrect Type value, returns super otherwise.
    """
    # If a change is made to column 'Type'
    if index.column() == 2:
        # If correct string, replace with correctly cased str
        if value.lower() == "liten":
            value = "Liten"
        elif value.lower() == "stor":
            value = "Stor"
        else:
            return False

    return super().setData(index, value, role)
class CodebookTableView (database)

TableView with a model of the 'Codebook'-table from database.

This modified QTableView creates a CodebookTableModel, which reads the Codebook-table. User can add, edit, delete and insert entries through this view.

Parameters

database : Database
Should be an instance of soitool.database.Database, and is used to create a QSqlDatabase from the database-file.

Raises

RuntimeError
If database does not open.
Expand source code
class CodebookTableView(QTableView):
    """TableView with a model of the 'Codebook'-table from database.

    This modified QTableView creates a CodebookTableModel, which reads the
    Codebook-table. User can add, edit, delete and insert entries through this
    view.

    Parameters
    ----------
    database : soitool.database.Database
        Should be an instance of soitool.database.Database, and is used to
        create a QSqlDatabase from the database-file.

    Raises
    ------
    RuntimeError
        If database does not open.
    """

    def __init__(self, database):
        super().__init__()
        db = QSqlDatabase.addDatabase(DBTYPE, CONNAME)
        db.setDatabaseName(database.db_path)

        if not db.open():
            raise RuntimeError("Could not open database.")

        # Enable sorting and hide vertical header
        self.setSortingEnabled(True)
        self.verticalHeader().hide()

        # Create and set model:
        model = CodebookTableModel()
        self.setModel(model)

        self.setEditTriggers(self.DoubleClicked)

        self.set_horizontal_header_text()

        # Set style of horizontal header
        header = self.horizontalHeader()
        header.setFont(CODEBOOK_HEADER_FONT)
        header.setStyleSheet(CODEBOOK_HEADER_BACKGROUND_CSS)

        self.setFixedWidth(600)

        self.resizeColumnsToContents()

    def set_horizontal_header_text(self):
        """Set Norwegian names in horizontal header."""
        self.model().setHeaderData(0, Qt.Horizontal, "Ord/Uttrykk")
        self.model().setHeaderData(1, Qt.Horizontal, "Kategori")
        self.model().setHeaderData(2, Qt.Horizontal, "Type")
        self.model().setHeaderData(3, Qt.Horizontal, "Kode")

    def close_db_connection(self):
        """Close database-connection."""
        self.setModel(None)
        QSqlDatabase.removeDatabase(CONNAME)

    def dataChanged(self, top_left, top_right, roles):
        """Resize column-width to contents when data changes.

        All parameters are sent to super.
        """
        super().dataChanged(top_left, top_right, roles)

        self.resizeColumnsToContents()

    def keyPressEvent(self, event):
        """Delete selected row and refresh view if delete-key was pressed.

        Parameters
        ----------
        event : QKeyEvent
            Describes a key event.
        """
        if event.key() == Qt.Key_Delete:
            index = self.currentIndex().row()
            self.model().removeRows(index, 1)
            self.model().select()
        super().keyPressEvent(event)

    def setModel(self, model):
        """Resize column-width to contents when a model is set.

        Parameter is sent to super.
        """
        super().setModel(model)
        if model is not None:
            self.set_horizontal_header_text()
            self.resizeColumnsToContents()

Ancestors

  • 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

Methods

def close_db_connection(self)

Close database-connection.

Expand source code
def close_db_connection(self):
    """Close database-connection."""
    self.setModel(None)
    QSqlDatabase.removeDatabase(CONNAME)
def dataChanged(self, top_left, top_right, roles)

Resize column-width to contents when data changes.

All parameters are sent to super.

Expand source code
def dataChanged(self, top_left, top_right, roles):
    """Resize column-width to contents when data changes.

    All parameters are sent to super.
    """
    super().dataChanged(top_left, top_right, roles)

    self.resizeColumnsToContents()
def keyPressEvent(self, event)

Delete selected row and refresh view if delete-key was pressed.

Parameters

event : QKeyEvent
Describes a key event.
Expand source code
def keyPressEvent(self, event):
    """Delete selected row and refresh view if delete-key was pressed.

    Parameters
    ----------
    event : QKeyEvent
        Describes a key event.
    """
    if event.key() == Qt.Key_Delete:
        index = self.currentIndex().row()
        self.model().removeRows(index, 1)
        self.model().select()
    super().keyPressEvent(event)
def setModel(self, model)

Resize column-width to contents when a model is set.

Parameter is sent to super.

Expand source code
def setModel(self, model):
    """Resize column-width to contents when a model is set.

    Parameter is sent to super.
    """
    super().setModel(model)
    if model is not None:
        self.set_horizontal_header_text()
        self.resizeColumnsToContents()
def set_horizontal_header_text(self)

Set Norwegian names in horizontal header.

Expand source code
def set_horizontal_header_text(self):
    """Set Norwegian names in horizontal header."""
    self.model().setHeaderData(0, Qt.Horizontal, "Ord/Uttrykk")
    self.model().setHeaderData(1, Qt.Horizontal, "Kategori")
    self.model().setHeaderData(2, Qt.Horizontal, "Type")
    self.model().setHeaderData(3, Qt.Horizontal, "Kode")