LargeDataSetExample Example

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../../shared")

from DevMachines import __pyside2__, __pyside6__
from DevMachines import QtitanBase
from DevMachines.QtitanBase import Qtitan
from DevMachines.QtitanGrid import (getGridVersion, Grid, GridColumn, GridEditor, GridCheckBox,
                                    CellButtonClickEventArgs, CellButtonEventArgs, ContextMenuEventArgs,
                                    EditorValidationEventArgs)

if __pyside2__:
    from PySide2 import QtCore
    from PySide2.QtCore import Qt, QTime, QDate, QAbstractItemModel, QStringListModel, QModelIndex
    from PySide2.QtWidgets import (QWidget, QApplication, QVBoxLayout, QHBoxLayout, QPushButton,
                                   QSlider, QLabel, QCheckBox, QComboBox, QMessageBox, QFileDialog)

if __pyside6__:
    from PySide6 import QtCore
    from PySide6.QtCore import Qt, QTime, QDate, QAbstractItemModel, QStringListModel, QModelIndex
    from PySide6.QtWidgets import (QWidget, QApplication, QVBoxLayout, QHBoxLayout, QPushButton,
                                   QSlider, QLabel, QCheckBox, QComboBox, QMessageBox, QFileDialog)

from DemoMainWindow import DemoMainWindow

def rand_value(low, high):
    return QtCore.QRandomGenerator.global_().generate() % ((high + 1) - low) + low

class DataItem:
    v0 = None
    v1 = None
    v2 = None
    v3 = None
    v4 = None
    v5 = None

class LargeDataSetModel(QAbstractItemModel):
    countryList = ["Germany", "France", "Italy", "United States", "United Kingdom", "Russia", "China", "Canada"]

    def __init__(self, parent):
        QAbstractItemModel.__init__(self, parent)

        self.values = list(range(0, 100000))
        y = 2009
        m = 1
        d = 1
        for i in self.values:
            item = DataItem()
            item.v0 = True
            item.v1 = i
            item.v2 = "String = " + str(i)
            item.v4 = QTime(12, 0, 0)
            if d > 28:
                d = 1
                m = m + 1
                if m > 12:
                    m = 1
                    y = y + 1

            item.v3 = QDate(y, m, d)
            if not ((i + 1) % 10):
                d = d + 1
            item.v5 = self.countryList[rand_value(0, 7)]
            self.values[i] = item

    def headerData(self, section, orientation, role):
        if section == 0:
            return "Boolean"
        elif section == 1:
            return "Integer"
        elif section == 2:
            return "String"
        elif section == 3:
            return "Date"
        elif section == 4:
            return "Time"
        elif section == 5:
            return "ComboBox"
        return None

    def parent(self, child):
        return QModelIndex()

    def hasChildren(self, parent):
        if parent.model() == self or not parent.isValid():
            return self.rowCount(parent) > 0 and self.columnCount(parent) > 0
        return False

    def rowCount(self, parent):
        if parent.isValid():
            return 0
        return len(self.values)

    def columnCount(self, parent):
        if parent.isValid():
            return 0
        return 6

    def index(self, row, column, parent):
        if parent.isValid():
            return QModelIndex()

        if row < 0 or row >= self.rowCount(parent):
            return QModelIndex()

        if column < 0 or column >= self.columnCount(parent):
            return QModelIndex()

        return self.createIndex(row, column, parent)

    def data(self, index, role):
        if not index.isValid():
            return None

        if index.row() < 0 or index.row() >= self.rowCount(index.parent()):
            return None

        if index.column() < 0 or index.column() >= self.columnCount(index.parent()):
            return None

        if role == Qt.DisplayRole or role == Qt.EditRole:
            if index.column() == 0:
                return self.values[index.row()].v0
            elif index.column() == 1:
                return self.values[index.row()].v1
            elif index.column() == 2:
                return self.values[index.row()].v2
            elif index.column() == 3:
                return self.values[index.row()].v3
            elif index.column() == 4:
                return self.values[index.row()].v4
            elif index.column() == 5:
                return self.values[index.row()].v5
        elif role == Qt.CheckStateRole:
            if index.column() == 0:
                return self.values[index.row()].v0
        return None

    def setData(self, index, value, role):
        if not index.isValid():
            return False

        if index.row() < 0 or index.row() >= self.rowCount(index.parent()):
            return False

        if index.column() < 0 or index.column() >= self.columnCount(index.parent()):
            return False

        if role != Qt.EditRole:
            return False

        if index.column() == 0:
            self.values[index.row()].v0 = bool(value)
        elif index.column() == 1:
            self.values[index.row()].v1 = int(value)
        elif index.column() == 2:
            self.values[index.row()].v2 = str(value)
        elif index.column() == 3:
            self.values[index.row()].v3 = value
        elif index.column() == 4:
            self.values[index.row()].v4 = value
        elif index.column() == 5:
            self.values[index.row()].v5 = str(value)

        self.dataChanged.emit(index, index)
        return True

    def flags(self, index):
        if not index.isValid():
            return Qt.ItemFlags()
        return Qt.ItemIsEnabled | Qt.ItemIsEditable

class Window(DemoMainWindow):
    def __init__(self):
        DemoMainWindow.__init__(self, "QtitanDataGrid", getGridVersion())

        self.setWindowTitle(self.tr("QtitanDataGrid - Large Model with 100.000 rows"))
        self.setGeometry(150, 150, 1000, 800)
        self.setMinimumHeight(10)

        Grid.loadTranslation()

        self.grid = Grid()
        model = LargeDataSetModel(self.grid)

        #  Configure grid view
        self.grid.setViewType(Grid.TableView)
        view = self.grid.view()
        view.options().setGridLineWidth(1)

        # Connect Grid's context menu handler.
        self.connect(view, QtCore.SIGNAL("contextMenu(ContextMenuEventArgs*)"), self,
            QtCore.SLOT("contextMenu(ContextMenuEventArgs*)"))
        self.connect(view, QtCore.SIGNAL("editorModifying(GridEditor *)"), self,
            QtCore.SLOT("editorModifying(GridEditor *)"))
        self.connect(view, QtCore.SIGNAL("editorValidating(EditorValidationEventArgs*)"), self,
            QtCore.SLOT("editorValidating(EditorValidationEventArgs*)"))
        self.connect(view, QtCore.SIGNAL("focusRowChanged(int, int)"), self,
            QtCore.SLOT("focusRowChanged(int, int)"))

        view.setModel(model)

        column = view.getColumn(0)
        column.setEditorType(GridEditor.CheckBox)
        column.editorRepository().setImmediatePost(True)

        column = view.getColumn(1)
        column.setEditorType(GridEditor.Numeric)
        column.editorRepository().setMinimum(-10000)
        column.editorRepository().setMaximum(10000)

        column = view.getColumn(2)
        column.setEditorType(GridEditor.String)
        column.editorRepository().setValidateOnEnter(False)
        column.editorRepository().setEditorActivationPolicy(GridEditor.ActivationPolicy(GridEditor.ActivateByKeyPress_WithEating | GridEditor.ActivateByEnter))

        # Add cell button to the column.
        column.addButton(GridColumn.TextButtonIcon, Qtitan.AtEnd)
        column.addButton(GridColumn.ChoiceButtonIcon, Qtitan.AtEnd)
        self.connect(column, QtCore.SIGNAL("buttonClicked(CellButtonClickEventArgs*)"), self,
            QtCore.SLOT("cellButtonClicked(CellButtonClickEventArgs*)"))

        column = view.getColumn(3)
        column.setEditorType(GridEditor.Date)
        # Add cell button to the column.
        column.addButton(GridColumn.ClearButtonIcon, Qtitan.AtEnd, GridColumn.MouseOverPolicy)
        self.connect(column, QtCore.SIGNAL("buttonClicked(CellButtonClickEventArgs*)"), self,
            QtCore.SLOT("cellButtonClicked(CellButtonClickEventArgs*)"))
        column.editorRepository().setAutoSelect(True)

        column = view.getColumn(4)
        column.setEditorType(GridEditor.Time)

        column = view.getColumn(5)
        column.setEditorType(GridEditor.ComboBox)

        countryModel = QStringListModel(column)
        countryModel.setStringList(LargeDataSetModel.countryList)
        column.dataBinding().setRelationModel(countryModel)
        column.dataBinding().setDefaultValue("", Qt.DisplayRole)
        column.dataBinding().setForeignKey(0, Qt.DisplayRole, Qt.DisplayRole)
        column.dataBinding().setRoleMapping(Qt.DisplayRole, 0, Qt.DisplayRole)

       # Show button menu for all column headers.
        for i in range(0, view.getColumnCount()):
            view.getColumn(i).setMenuButtonVisible(True)

        self.setDemoWidget(self.grid, self.createSettingsWidget())

    def createSettingsWidget(self):
        # Create settings widget
        settings = QWidget(self)
        l = QVBoxLayout(settings)
        autoWidthCheck = QCheckBox(settings)
        autoWidthCheck.setText("Column auto width")
        self.connect(autoWidthCheck, QtCore.SIGNAL("stateChanged(int)"), self,
            QtCore.SLOT("autoWidthStateChanged(int)"))
        autoWidthCheck.setChecked(True)
        l.addWidget(autoWidthCheck)

        fastScrollCheck = QCheckBox(settings)
        fastScrollCheck.setText("Fast scroll effect")
        self.connect(fastScrollCheck, QtCore.SIGNAL("stateChanged(int)"), self,
            QtCore.SLOT("fastScrollChanged(int)"))
        l.addWidget(fastScrollCheck)
        fastScrollCheck.setChecked(True)

        dottedLineCheck = QCheckBox(settings)
        dottedLineCheck.setText("Dotted grid line")
        self.connect(dottedLineCheck, QtCore.SIGNAL("stateChanged(int)"), self,
            QtCore.SLOT("dottedLineChanged(int)"))
        l.addWidget(dottedLineCheck)
        dottedLineCheck.setChecked(True)

        label = QLabel(self)
        hl = QHBoxLayout()
        label.setText("Grid line style:")
        lineStylesSelect = QComboBox(settings)

        lineStylesSelect.addItem("None")
        lineStylesSelect.addItem("Both")
        lineStylesSelect.addItem("Both2D")
        lineStylesSelect.addItem("Horizontal")
        lineStylesSelect.addItem("Horizontal2D")
        lineStylesSelect.addItem("Vertical")
        lineStylesSelect.addItem("Vertical2D")
        self.connect(lineStylesSelect, QtCore.SIGNAL("currentIndexChanged(int)"), self, QtCore.SLOT("selectGridLineStyles(int)"))
        hl.addWidget(label)
        hl.addWidget(lineStylesSelect)
        l.addLayout(hl)
        lineStylesSelect.setCurrentIndex(2)

        zoomEnable = QCheckBox(settings)
        zoomEnable.setText(self.tr("Zoom enabled"))
        zoomEnable.setChecked(True)
        self.connect(zoomEnable, QtCore.SIGNAL("stateChanged(int)"), self, QtCore.SLOT("zoomEnabledChanged(int)"))
        l.addWidget(zoomEnable)

        zoomIndicator = QCheckBox(settings)
        zoomIndicator.setText(self.tr("Show zoom indicator"))
        zoomIndicator.setChecked(True)
        self.connect(zoomIndicator, QtCore.SIGNAL("stateChanged(int)"), self, QtCore.SLOT("zoomIndicatorChanged(int)"))
        l.addWidget(zoomIndicator)

        zoomSlider = QSlider(settings)
        zoomSlider.setOrientation(Qt.Horizontal)
        zoomSlider.setTickPosition(QSlider.TicksBothSides)
        zoomSlider.setMinimum(25)
        zoomSlider.setMaximum(300)
        zoomSlider.setTickInterval(25)
        zoomSlider.setSingleStep(25)
        zoomSlider.setValue(100)
        self.connect(zoomSlider, QtCore.SIGNAL("sliderMoved(int)"), self, QtCore.SLOT("zoomValueChanged(int)"))
        self.connect(self.grid.view(), QtCore.SIGNAL("zoomChanged(int)"), zoomSlider, QtCore.SLOT("setValue(int)"))
        l.addWidget(zoomSlider)

        cellAutoRaise = QCheckBox(settings)
        cellAutoRaise.setText(self.tr("Auto raise cell button"))
        self.connect(cellAutoRaise, QtCore.SIGNAL("stateChanged(int)"), self, QtCore.SLOT("cellButtonAutoRaiseEnabled(int)"))
        cellAutoRaise.setChecked(True)
        l.addWidget(cellAutoRaise)

        frozenRowsBox = QCheckBox(settings)
        frozenRowsBox.setText(self.tr("Frozen Rows"))
        self.connect(frozenRowsBox, QtCore.SIGNAL("stateChanged(int)"), self, QtCore.SLOT("frozenRowsEnabled(int)"))
        frozenRowsBox.setChecked(True)
        l.addWidget(frozenRowsBox)

        transparentBox = QCheckBox(settings)
        transparentBox.setText(self.tr("Transparent Background"))
        self.connect(transparentBox, QtCore.SIGNAL("stateChanged(int)"), self, QtCore.SLOT("transparentBackgroundEnabled(int)"))
        transparentBox.setChecked(False)
        l.addWidget(transparentBox)

        label = QLabel(self)
        hl = QHBoxLayout()
        label.setText("Check box appearance (new):")
        checkBoxAppearance = QComboBox(settings)

        checkBoxAppearance.addItem("CheckBox")
        checkBoxAppearance.addItem("RadioButton")
        checkBoxAppearance.addItem("Styled")
        self.connect(checkBoxAppearance, QtCore.SIGNAL("currentIndexChanged(int)"), self, QtCore.SLOT("checkBoxAppearanceChanged(int)"))
        hl.addWidget(label)
        hl.addWidget(checkBoxAppearance)
        l.addLayout(hl)
        checkBoxAppearance.setCurrentIndex(2)

        printButton = QPushButton(settings)
        printButton.sizeHint()
        printButton.setText(self.tr("Print Preview"))
        self.connect(printButton, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("printPreview()"))
        l.addWidget(printButton)

        return settings

    def setShadeColor(self, color):
        self.grid.themeManager().setShadeColor(color)

    @QtCore.Slot(int)
    def autoWidthStateChanged(self, state):
        view = self.grid.view()
        view.tableOptions().setColumnAutoWidth(Qt.CheckState(state) == Qt.Checked)

    @QtCore.Slot(int)
    def fastScrollChanged(self, state):
        view = self.grid.view()
        view.options().setFastScrollEffect(Qt.CheckState(state) == Qt.Checked)

    @QtCore.Slot(int)
    def dottedLineChanged(self, state):
        view = self.grid.view()
        pen = view.options().gridLinePen()
        if Qt.CheckState(state) == Qt.Checked:
            pen.setStyle(Qt.DotLine)
        else:
            pen.setStyle(Qt.SolidLine)
        view.options().setGridLinePen(pen)

    @QtCore.Slot(int)
    def selectGridLineStyles(self, index):
        view = self.grid.view()
        if index == 0:
            view.options().setGridLines(Qtitan.LinesNone)
        elif index == 1:
            view.options().setGridLines(Qtitan.LinesBoth)
        elif index == 2:
            view.options().setGridLines(Qtitan.LinesBoth2D)
        elif index == 3:
            view.options().setGridLines(Qtitan.LinesHorizontal)
        elif index == 4:
            view.options().setGridLines(Qtitan.LinesHorizontal2D)
        elif index == 5:
            view.options().setGridLines(Qtitan.LinesVertical)
        elif index == 6:
            view.options().setGridLines(Qtitan.LinesVertical2D)
        else:
            view.options().setGridLines(Qtitan.LinesBoth)

    @QtCore.Slot(int)
    def checkBoxAppearanceChanged(self, index):
        view = self.grid.view()
        column = view.getColumn(0)
        if index == 0:
            column.editorRepository().setAppearance(GridCheckBox.CheckBoxAppearance)
        elif index == 1:
            column.editorRepository().setAppearance(GridCheckBox.RadioButtonAppearance)
        else:
            column.editorRepository().setAppearance(GridCheckBox.StyledAppearance)

    @QtCore.Slot(int)
    def zoomEnabledChanged(self, state):
        view = self.grid.view()
        view.options().setZoomEnabled(Qt.CheckState(state) == Qt.Checked)

    @QtCore.Slot(int)
    def zoomIndicatorChanged(self, state):
        view = self.grid.view()
        view.options().setZoomIndicatorActive(Qt.CheckState(state) == Qt.Checked)

    @QtCore.Slot(int)
    def zoomValueChanged(self, value):
        factor = (float(value) / 25) * 25
        view = self.grid.view()
        view.options().setZoomFactor(factor / 100)

    def focusRowChanged(self, oldRowIndex, rowIndex):
        oldRowIndex = rowIndex

    @QtCore.Slot(int)
    def cellButtonAutoRaiseEnabled(self, state):
        view = self.grid.view()
        view.options().setCellButtonAutoRaise(Qt.CheckState(state) == Qt.Checked)

    @QtCore.Slot(int)
    def frozenRowsEnabled(self, state):
        view = self.grid.view()
        view.tableOptions().setRowFrozenButtonVisible(Qt.CheckState(state) == Qt.Checked)
        view.tableOptions().setFrozenPlaceQuickSelection(Qt.CheckState(state) == Qt.Checked)

    @QtCore.Slot(int)
    def transparentBackgroundEnabled(self, state):
        view = self.grid.view()
        view.options().setTransparentBackground(Qt.CheckState(state) == Qt.Checked)
        view.options().setAlternatingRowColors(not view.options().alternatingRowColors())

    @QtCore.Slot(GridEditor)
    def editorModifying(self, editor):
        editor = editor

    @QtCore.Slot(EditorValidationEventArgs)
    def editorValidating(self, args):
        args.setValueValid(True)
        #args.setEditingValue(args.editValue())
        args.setHandled(True)

    @QtCore.Slot(ContextMenuEventArgs)
    def contextMenu(self, args):
        args.contextMenu().addAction("Print Preview", self, QtCore.SLOT("printPreview()"))
        args.contextMenu().addSeparator()
        args.contextMenu().addAction("Developer Machines on the Web", self, QtCore.SLOT("showCompanyWebSite()"))

    @QtCore.Slot(CellButtonClickEventArgs)
    def cellButtonClicked(self, args):
        QMessageBox.information(self, "Cell button clicked",
            "Clicked: Button - " + str(args.buttonIndex()) + ", Column Title - " + args.column().caption() + ", RowIndex - " + str(args.row().rowIndex()))

    @QtCore.Slot()
    def printPreview(self):
        self.grid.view().printPreview()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())