#!/usr/bin/env python

import sys
from PyQt4 import QtCore, QtGui

table = ['H','He','Li','Be','B','C','N','O','F','Ne']

class ElementValidator(QtGui.QValidator):
    def __init__(self, parent = None):
        QtGui.QValidator.__init__(self, parent)
        self.regexp = QtCore.QRegExp("[A-Z]")
        print "validator created"

    def validate(self, inputStr, pos):
        print "validating"
        if len(inputStr) > 2:
            return (QtGui.QValidator.Invalid,pos)

        if not self.regexp.exactMatch(inputStr[0]):
            return (QtGui.QValidator.Invalid,pos)

        try:
            table.index(inputStr)
        except ValueError:
            return (QtGui.QValidator.Intermediate,pos)
        else:
            return (QtGui.QValidator.Acceptable,pos)

class CustomDelegate(QtGui.QItemDelegate):
    def __init__(self, parent = None):
        QtGui.QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        editor = QtGui.QLineEdit(parent)
        if index.column() == 0:
            validator = ElementValidator(editor) #QtGui.QRegExpValidator(QtCore.QRegExp("[A-Z][a-z]"),editor)
        else:
            validator = QtGui.QDoubleValidator(-1000,1000,5,editor)
        editor.setValidator(validator)
            
        editor.installEventFilter(self)

        return editor

    def setEditorData(self, lineEdit, index):
        value = index.model().data(index, QtCore.Qt.DisplayRole).toString()
        lineEdit.setText(value)

    def setModelData(self, lineEdit, model, index):
        value = lineEdit.text()
        if value == "":
            return

        if index.column() > 0:
            value = "%7.3f" % float(value)

        model.setData(index, QtCore.QVariant(value))

    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)

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

    delegate = CustomDelegate()
    tableView.setItemDelegate(delegate)

    for row in range(4):
        for column in range(2):
            index = model.index(row, column, QtCore.QModelIndex())
            model.setData(index, QtCore.QVariant((row+1) * (column+1)))

    tableView.setWindowTitle("Spin Box Delegate")
    tableView.show()
    sys.exit(app.exec_())
