HtmlManipulation 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, GridSummary, GridEditor,
GridViewOptions,
CellButtonClickEventArgs, ContextMenuEventArgs,
ColumnLinkEventArgs, PreviewRowLinkEventArgs, EditorLinkEventArgs)
if __pyside2__:
from PySide2 import QtCore
from PySide2.QtCore import Qt, QDate, QAbstractItemModel, QModelIndex
from PySide2.QtWidgets import (QWidget, QApplication, QVBoxLayout, QHBoxLayout, QPushButton,
QSlider, QLabel, QCheckBox, QComboBox, QMessageBox)
if __pyside6__:
from PySide6 import QtCore
from PySide6.QtCore import Qt, QDate, QAbstractItemModel, QModelIndex
from PySide6.QtWidgets import (QWidget, QApplication, QVBoxLayout, QHBoxLayout, QPushButton,
QSlider, QLabel, QCheckBox, QComboBox, QMessageBox)
from DemoMainWindow import DemoMainWindow
class DataItem:
v0 = None
v1 = None
v2 = None
v3 = None
v4memo = None
v5 = None
class HthmlManipulationModel(QAbstractItemModel):
def __init__(self, parent):
QAbstractItemModel.__init__(self, parent)
self.values = list(range(0, 100))
y = 2009
m = 1
d = 1
for i in self.values:
item = DataItem()
item.v0 = True
item.v1 = i
item.v2 = "String-1: " + str(i)
item.v3 = "String-2: " + str(i)
item.v4memo = """<a href='#link_""" + str(i) + """"'>Lorem ipsum</a> dolor sit amet, consectetur adipiscing elit. Nullam sodales,
libero at hendrerit commodo, urna velit vestibulum purus, cursus dignissim tellus ante non leo."""
if d > 28:
d = 1
m = m + 1
if m > 12:
m = 1
y = y + 1
item.v5 = QDate(y, m, d)
if not ((i + 1) % 10):
d = d + 1
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 "String"
elif section == 4:
return "Memo"
elif section == 5:
return "Date"
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.WhatsThisRole:
previewText = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam sodales,
libero at hendrerit commodo, urna velit vestibulum purus, cursus dignissim tellus ante non leo.
<h2>Duis quam lorem, bibendum id luctus eu, consequat at purus</h2>.
<a href='#preview_link'>Test Preview Link</a>
Duis quam lorem, bibendum id luctus eu, consequat at purus. Curabitur posuere ligula eu turpis porttitor faucibus rhoncus neque pretium.
Aenean ut urna felis."""
return previewText
elif 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()].v4memo
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 = str(value)
elif index.column() == 4:
self.values[index.row()].v4memo = str(value)
elif index.column() == 5:
self.values[index.row()].v5 = 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 - HTML Manipulation"))
self.setGeometry(150, 150, 1100, 900)
Grid.loadTranslation()
self.grid = Grid()
model = HthmlManipulationModel(self.grid)
# Configure grid view
self.grid.setViewType(Grid.BandedTableView)
view = self.grid.view()
view.addBand("Section 1")
view.addBand("Section 2")
view.addBand("Section 3")
view.options().setFooterSummaryVisible(False)
view.options().setGroupSummaryPlace(GridViewOptions.SummaryRow)
view.options().setPreviewRowEnabled(True)
view.options().setPreviewExpandButtonVisible(False)
view.modelController().previewRowDataBinding().setDisplayRole(Qt.WhatsThisRole)
view.options().setPreviewRowHeight(150)
view.options().setScrollRowStyle(Qtitan.ScrollByPixel)
band = view.getBand(0)
band.setHtmlCaption("<i>Section</i> <b>One</b> <a href='#test1'>Link 1</a>")
band = view.getBand(1)
band.setHtmlCaption("<i>Section</i> <b>Two</b> <a href='#test2'>Link 2</a>")
band = view.getBand(2)
band.setHtmlCaption("<i>Section</i> <b>Three</b> <a href='#test3'>Link 3</a>")
# Connect Grid's context menu handler.
self.connect(view, QtCore.SIGNAL("contextMenu(ContextMenuEventArgs*)"), self, QtCore.SLOT("contextMenu(ContextMenuEventArgs*)"))
# Connect link activation handlers.
self.connect(view, QtCore.SIGNAL("previewLinkActivated(PreviewRowLinkEventArgs*)"), self,
QtCore.SLOT("previewLinkActivated(PreviewRowLinkEventArgs*)"))
self.connect(view, QtCore.SIGNAL("columnLinkActivated(ColumnLinkEventArgs*)"), self,
QtCore.SLOT("columnLinkActivated(ColumnLinkEventArgs*)"))
self.connect(view, QtCore.SIGNAL("editorLinkActivated(EditorLinkEventArgs*)"), self,
QtCore.SLOT("editorLinkActivated(EditorLinkEventArgs*)"))
self.connect(view, QtCore.SIGNAL("summaryGroupTextChanging(SummaryGroupTextEventArgs*)"), self,
QtCore.SLOT("summaryGroupTextChanging(SummaryGroupTextEventArgs*)"))
view.setModel(model)
column = view.getColumn(0)
column.setBandIndex(0)
# Configure the summary
column.setDefaultGroupSummary(GridSummary.Max)
column.setDecorationColor(Qt.yellow)
column = view.getColumn(1)
column.setBandIndex(1)
column.setRowIndex(0)
# Configure the summary
column.setDefaultGroupSummary(GridSummary.Avg)
column.setFooterSummary(GridSummary.Avg)
column = view.getColumn(2)
column.setBandIndex(1)
column.setRowIndex(1)
column.setHtmlCaption("<font color='red'>Column</font> with <a href='#string_column1'>HTML Caption</a>")
# Configure the summary
column.setDefaultGroupSummary(GridSummary.Count)
column.setFooterSummary(GridSummary.Count)
column = view.getColumn(3)
column.setBandIndex(1)
column.setRowIndex(2)
# Add cell button to the column.
column.addButton()
self.connect(column, QtCore.SIGNAL("buttonClicked(CellButtonClickEventArgs*)"), self,
QtCore.SLOT("cellButtonClicked(CellButtonClickEventArgs*)"))
column = view.getColumn(4)
column.setBandIndex(2)
column.setEditorType(GridEditor.Memo)
column.editorRepository().setHTML(True)
column.setRowSpan(3)
column = view.getColumn(5)
column.setBandIndex(0)
column.setRowSpan(2)
column.setRowIndex(1)
column.setGroupIndex(0)
# Configure the summary
column.setDefaultGroupSummary(GridSummary.Min)
column.setFooterSummary(GridSummary.Max)
view.expandAll()
# 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):
settings = QWidget(self)
l = QVBoxLayout(settings)
autoWidthCheck = QCheckBox(settings)
l.addWidget(autoWidthCheck)
autoWidthCheck.setText("Column auto width")
self.connect(autoWidthCheck, QtCore.SIGNAL("stateChanged(int)"), self, QtCore.SLOT("autoWidthStateChanged(int)"))
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(False)
label = QLabel(settings)
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
def setShadeColor(self, color):
Grid.themeManager().setShadeColor(color)
@QtCore.Slot(PreviewRowLinkEventArgs)
def previewLinkActivated(self, args):
QMessageBox.information(self, self.tr("Preview link clicked"), "Clicked: RowIndex " + str(args.row().rowIndex()) + ", Link " + args.anchor())
@QtCore.Slot(ColumnLinkEventArgs)
def columnLinkActivated(self, args):
if args.column().inherits("Qtitan::GridTableBand"):
QMessageBox.information(self, self.tr("Band Column HTML link clicked"), "Clicked: Band " + args.column().caption() + ", Link " + args.anchor())
else:
QMessageBox.information(self, self.tr("Column HTML link clicked"), "Clicked: Column " + args.column().caption() + ", Link " + args.anchor())
@QtCore.Slot(EditorLinkEventArgs)
def editorLinkActivated(self, args):
QMessageBox.information(self, self.tr("Cell Editor link clicked"),
"Column " + args.column().caption() + ", RowIndex " + str(args.row().rowIndex()) + ", Link " + args.anchor())
@QtCore.Slot(EditorLinkEventArgs)
def summaryGroupTextChanging(self, args):
if args.dataBinding().column() == 1:
args.setTextColor(Qt.red)
@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()
if __name__ == "__main__":
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())