ColumnEditorsFeature 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,
                                    GridColumnEditor,
                                    ContextMenuEventArgs,
                                    CellButtonClickEventArgs)

if __pyside2__:
    from PySide2 import QtCore
    from PySide2.QtCore import Qt, QFile, QTextStream, QAbstractItemModel, QItemSelectionModel, QModelIndex
    from PySide2.QtGui import QColor, QStandardItemModel
    from PySide2.QtWidgets import (QWidget, QApplication, QVBoxLayout, QHBoxLayout, QPushButton,
                                   QSlider, QLabel, QCheckBox, QComboBox, QMessageBox, QTableView, QFrame)

if __pyside6__:
    from PySide6 import QtCore
    from PySide6.QtCore import Qt, QFile, QTextStream, QAbstractItemModel, QItemSelectionModel, QModelIndex
    from PySide6.QtGui import QColor, QStandardItemModel
    from PySide6.QtWidgets import (QWidget, QApplication, QVBoxLayout, QHBoxLayout, QPushButton,
                                   QSlider, QLabel, QCheckBox, QComboBox, QMessageBox, QTableView, QFrame)

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

import chart_rc

from DemoMainWindow import DemoMainWindow

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

    def headerData(self, section, orientation, role):
        return "Column " + str(section)

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

    def hasChildren(self, parent):
        if parent.model() == self or not parent.isValid():
            return False
        return False

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

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

    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:
            return index.row()

        if role == Qt.DecorationRole:
            if index.column() == 5 and index.row() >= 3 and index.row() < 10:
                return QColor(Qt.red)

        if index.column() == 7 and index.row() >= 5 and index.row() < 15:
            return QColor(Qt.gray)

        return None

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

class GridChartColumnEditor(GridColumnEditor):
    def __init__(self):
        GridColumnEditor.__init__(self)
        self.model = QStandardItemModel(8, 2, self)
        self.model.setHeaderData(0, Qt.Horizontal, self.tr("Label"))
        self.model.setHeaderData(1, Qt.Horizontal, self.tr("Quantity"))
        self.selectionModel = QItemSelectionModel(self.model)

    def createEditorWidget(self, column):
        view = QTableView()
        view.setFrameShape(QFrame.NoFrame)
        view.setModel(self.model)
        self.loadModel(":/Charts/qtdata.cht")
        view.setSelectionModel(self.selectionModel)
        return view

    def loadModel(self, fileName):
        if fileName != "":
            file = QFile(fileName)
            if file.open(QFile.ReadOnly | QFile.Text):
                stream = QTextStream(file)
                self.model.removeRows(0, self.model.rowCount(QModelIndex()), QModelIndex())

                row = 0
                while True:
                    line = stream.readLine()
                    if line == "":
                        break;

                    self.model.insertRows(row, 1, QModelIndex())
                    pieces = line.split(",")
                    self.model.setData(self.model.index(row, 0, QModelIndex()),
                                    pieces[0])
                    self.model.setData(self.model.index(row, 1, QModelIndex()),
                                    pieces[1])
                    self.model.setData(self.model.index(row, 0, QModelIndex()),
                                    QColor(pieces[2]), Qt.DecorationRole)
                    row = row + 1

            file.close()

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

        self.setWindowTitle(self.tr("QtitanDataGrid Column Editor Demo (Banded table view)"))
        self.setGeometry(150, 150, 1000, 800)

        Grid.loadTranslation()

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

        # Configure grid view
        self.grid.setViewType(Grid.BandedTableView)
        view = self.grid.view()
        view.options().setModelDecoration(True)
        view.bandedOptions().setBandHeight(220)

        # Connect Grid's context menu handler.
        self.connect(view, QtCore.SIGNAL("contextMenu(ContextMenuEventArgs*)"), self,
            QtCore.SLOT("contextMenu(ContextMenuEventArgs* )"))

        engineeringBand = view.addBand("Engineering")
        characteristics1 = view.addBand("Characteristics 1")
        characteristics2 = view.addBand("Characteristics 2")
        characteristics3 = view.addBand("Characteristics 3")
        chartEditor = GridChartColumnEditor()
        characteristics1.setColumnEditor(chartEditor)
        characteristics2.setColumnEditor(chartEditor)
        characteristics3.setColumnEditor(chartEditor)
        engineeringBand.setFixedPosition(Qtitan.AtBeginning)
        view.setModel(model)

        column = view.getColumnByModelColumnName("Column 0")
        column.setBandIndex(engineeringBand.index())
        column = view.getColumnByModelColumnName("Column 1")
        column.setBandIndex(engineeringBand.index())
        # Add cell button to the column.
        column.addButton(GridColumn.ClearButtonIcon)
        self.connect(column, QtCore.SIGNAL("buttonClicked(CellButtonClickEventArgs*)"), self,
            QtCore.SLOT("cellButtonClicked(CellButtonClickEventArgs*)"))

        column = view.getColumnByModelColumnName("Column 2")
        column.setBandIndex(engineeringBand.index())
        # Add cell button to the column.
        column.addButton(GridColumn.ChoiceButtonIcon)
        self.connect(column, QtCore.SIGNAL("buttonClicked(CellButtonClickEventArgs*)"), self,
            QtCore.SLOT("cellButtonClicked(CellButtonClickEventArgs*)"))

        column = view.getColumnByModelColumnName("Column 3")
        column.setBandIndex(characteristics1.index())
        column = view.getColumnByModelColumnName("Column 4")
        column.setBandIndex(characteristics1.index())
        column = view.getColumnByModelColumnName("Column 5")
        column.setBandIndex(characteristics1.index())

        column = view.getColumnByModelColumnName("Column 6")
        column.setBandIndex(characteristics2.index())
        column = view.getColumnByModelColumnName("Column 7")
        column.setBandIndex(characteristics2.index())
        column = view.getColumnByModelColumnName("Column 8")
        column.setBandIndex(characteristics2.index())

        column = view.getColumnByModelColumnName("Column 9")
        column.setBandIndex(characteristics3.index())
        column = view.getColumnByModelColumnName("Column 10")
        column.setBandIndex(characteristics3.index())
        column = view.getColumnByModelColumnName("Column 11")
        column.setBandIndex(characteristics3.index())

        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)"))
        l.addWidget(autoWidthCheck)
        autoWidthCheck.setChecked(True)

        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)

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

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

    @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(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()

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

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