Page List

Friday, January 27, 2012

Qt 4.8 Model/View Tutorial - Part 8

The following code is based on the Qt Spin Box Delegate Example.



#!/usr/bin/env python3
# -*- coding: utf-8 -*-

'''
    PyQt4 conversion of Qt Model-View Tutorial
    
     The Spin Box Delegate example shows how to create an editor for a 
     custom delegate in the model/view framework by reusing a standard 
     Qt editor widget.

    The model/view framework provides a standard delegate that is used 
    by default with the standard view classes. For most purposes, the 
    selection of editor widgets available through this delegate is 
    sufficient for editing text, boolean values, and other simple data 
    types. However, for specific data types, it is sometimes necessary 
    to use a custom delegate to either display the data in a specific 
    way, or allow the user to edit it with a custom control.
     
    NOTES:
    =====
    In the C++ code, static_casts are used to cast the
    editor to a QSpinBox; this isn't necessary in Python
      
last modified: 2012-01-28 jg
ref:
    http://developer.qt.nokia.com/doc/qt-4.8/itemviews-spinboxdelegate.html
    
'''
from PyQt4.QtGui import (QApplication, QMainWindow, QItemDelegate, QTableView,
                         QStyleOptionViewItem, QSpinBox, QStandardItemModel)
from PyQt4.QtCore import (Qt, QModelIndex)

class SpinBoxDelegate(QItemDelegate):
    def __init__(self, parent=None):    # initialise base class
        super(SpinBoxDelegate, self).__init__(parent)

        # no further initialisation required

    def createEditor(self, parent, option, index):
        # create an editor that restricts values from the model 
        # to integers between between 0 and 100
        editor = QSpinBox(parent)
        editor.setMinimum(0)
        editor.setMaximum(100)

        return editor

    def setEditorData(self, editor, index):
        # get the data from the model and update the editor
        value = index.model().data(index, Qt.EditRole)
        editor.setValue(value)

    def setModelData(self, editor, model, index):
        # read the contents of the spin box and update the model
        editor.interpretText()
        value = editor.value()
        model.setData(index, value, Qt.EditRole)

    def updateEditorGeometry(self, editor, option, index):
        # update the editor's geometry using information
        # from the style option
        editor.setGeometry(option.rect)

class MainWindow(QMainWindow):
    def __init__(self, parent=None):    # initialise base class
        super(MainWindow, self).__init__(parent)

        model = QStandardItemModel(4, 2)
        tableView = QTableView(self)
        tableView.setModel(model)

        tableView.setItemDelegate(SpinBoxDelegate(self))

        tableView.horizontalHeader().setStretchLastSection(True)

        # insert example data
        for row in range(4):
            for col in range(2):
                index = model.index(row, col, QModelIndex())
                model.setData(index, (row + 1) * (col + 1))

        self.setCentralWidget(tableView)

# main ========================================================================
def main():
    import sys

    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.setWindowTitle("Spin Box Delegate Example")
    mw.show()

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()