Skip to content

Instantly share code, notes, and snippets.

@zhanglongqi
Created February 1, 2016 09:43
Show Gist options
  • Save zhanglongqi/90c73fdb4478f2644725 to your computer and use it in GitHub Desktop.
Save zhanglongqi/90c73fdb4478f2644725 to your computer and use it in GitHub Desktop.
Delegate example
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
longqi 21/Jan/16 15:36
"""#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sys
from datetime import date
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import Qt
def setup_model():
class TestModel(QtCore.QAbstractTableModel):
def __init__(self, columns, rows):
QtCore.QAbstractTableModel.__init__(self)
self.rows = rows
self.columns = columns
def columnCount(self, index):
return len(self.columns)
def rowCount(self, index):
return len(self.rows)
def data(self, index, role):
if index.isValid():
field_id = self.columns[index.column()]
value = getattr(self.rows[index.row()], field_id)
if (role == Qt.EditRole) or (role == Qt.DisplayRole) or (role == Qt.ToolTipRole):
return value
def setData(self, index, value, role=Qt.EditRole):
if index.isValid() and role == Qt.EditRole:
field_id = self.columns[index.column()]
setattr(self.rows[index.row()], field_id, value)
return True
class Person(object):
def __init__(self, name, birthday):
self.name = name
self.birthday = birthday
fields = ['name', 'birthday']
rows = [
Person(u'Peter Ivanov', 12),
Person(u'Masha Poryvayeva', 14),
Person(u'Helge Seppälla', 15)
]
return TestModel(fields, rows)
class DateDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
QtGui.QStyledItemDelegate.__init__(self, parent)
def createEditor(self, parent, option, index):
pass
def setEditorData(self, lineEdit, index):
value = index.model().data(index, QtCore.Qt.EditRole)
lineEdit.setText(str(value))
def setModelData(self, lineEdit, model, index):
value = lineEdit.text()
model.setData(index, value)
class LineDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
QtGui.QStyledItemDelegate.__init__(self, parent)
def createEditor(self, parent, option, index):
pass
def setEditorData(self, editor, index):
editor.setText(index.model().data(index, QtCore.Qt.EditRole))
def setModelData(self, editor, model, index):
model.setData(index, editor.text(), QtCore.Qt.EditRole)
class DelegateProxy(QtGui.QStyledItemDelegate):
# that's the delegate proxy, forwarding data to real delegates that will handle it properly
def __init__(self, delegates, parent=None):
QtGui.QStyledItemDelegate.__init__(self, parent)
self.delegates = delegates
def setEditorData(self, editor, index):
# that is kinda naive and depends on column order in the model.
# you should implement your own, more reliable way to link item index
# and a delegate, responsible for handling the item
delegate = self.delegates[index.column()]
delegate.setEditorData(editor, index)
def setModelData(self, editor, model, index):
delegate = self.delegates[index.column()]
delegate.setModelData(editor, model, index)
class MyEditWindow(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setLayout(QtGui.QFormLayout(self))
self.model = setup_model()
self.data_mapper = QtGui.QDataWidgetMapper(self)
self.data_mapper.setModel(self.model)
# creating widgets
self.name = QtGui.QLineEdit(self)
self.layout().addRow('Name:', self.name)
self.birthday = QtGui.QLineEdit(self)
self.layout().addRow('Birthday:', self.birthday)
# and mapping them
self.data_mapper.addMapping(self.name, 0)
self.data_mapper.addMapping(self.birthday, 1)
# setting up multiple delegates
delegates = [LineDelegate(self), DateDelegate(self)]
self.data_mapper.setItemDelegate(DelegateProxy(delegates, self))
self.data_mapper.toFirst()
# additional stuff
self.btn_prev = QtGui.QPushButton('Prev.', self)
self.btn_prev.clicked.connect(self.data_mapper.toPrevious)
self.btn_next = QtGui.QPushButton('Next', self)
self.btn_next.clicked.connect(self.data_mapper.toNext)
self.buttons_layout = QtGui.QHBoxLayout()
self.layout().addRow(self.buttons_layout)
self.buttons_layout.addWidget(self.btn_prev)
self.buttons_layout.addWidget(self.btn_next)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MyEditWindow()
window.show()
app.exec_()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment