Advertisement
AlexVhr

Qt MVF custom editor troubles

Jan 30th, 2013
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.22 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3.  
  4. """Trying to implement a simple custom editor for Qt's MV-framework.
  5. Problems:
  6. The editor (MyButtonEdit) does not update model data on focus out event, when placed
  7. on a form and mapped to QDataWidgetMapper. It works fine in QTableView though.
  8. """
  9.  
  10. import sys
  11.  
  12. from PySide import QtGui, QtCore
  13. from PySide.QtCore import Qt
  14.  
  15.  
  16. class EmbeddedButton(QtGui.QToolButton):
  17.  
  18.     def __init__(self, parent, text, icon=None, slot=None, shortcut=None, tooltip=None):
  19.         super().__init__(parent)
  20.         self.setCursor(QtCore.Qt.ArrowCursor)
  21.         self.setFocusPolicy(Qt.NoFocus)
  22.         self.setText(text)
  23.  
  24.         if slot:
  25.             self.clicked.connect(slot)
  26.         if shortcut:
  27.             self.setShortcut(shortcut)
  28.         if tooltip:
  29.             self.setToolTip(tooltip)
  30.  
  31. class ButtonEdit(QtGui.QWidget):
  32.  
  33.     def __init__(self, parent=None):
  34.         super().__init__(parent)
  35.         layout = QtGui.QHBoxLayout()
  36.         layout.setContentsMargins(0, 0, 0, 0)
  37.         layout.setSpacing(0)
  38.  
  39.         self.setLayout(layout)
  40.         self.line_edit = QtGui.QLineEdit(self)
  41.  
  42.         self.text = self.line_edit.text
  43.         self.setText = self.line_edit.setText
  44.  
  45.         self.layout().addWidget(self.line_edit)
  46.         self.buttons = {}
  47.         self.setFocusProxy(self.line_edit)
  48.         self.line_edit.installEventFilter(self)
  49.  
  50.     def eventFilter(self, target, event):
  51.         if target == self.line_edit:
  52.             if event.type() == QtCore.QEvent.KeyPress:
  53.                 if event.key() == Qt.Key_Tab:
  54.                     self.keyPressEvent(event)
  55.                     return True
  56.             elif event.type() == QtCore.QEvent.FocusOut:
  57.                 self.focusOutEvent(event)
  58.                 #can not return True - the imput cursor will duplicate.
  59.                 # And the data will not be updated anyway.
  60.         return False
  61.  
  62.  
  63.     def addButton(self, id, text, icon=None, slot=None, shortcut=None, tooltip=None):
  64.         button = EmbeddedButton(self, text, icon, slot, shortcut, tooltip)
  65.         self.layout().addWidget(button)
  66.         self.buttons[id] = button
  67.  
  68.  
  69. class MyButtonEdit(ButtonEdit):
  70.     def __init__(self, parent=None):
  71.         super().__init__(parent)
  72.         self.addButton('first', '1')
  73.         self.addButton('second','2')
  74.         self.addButton('third','3')
  75.  
  76.  
  77. class MyDelegate(QtGui.QStyledItemDelegate):
  78.  
  79.     def __init__(self, parent):
  80.         QtGui.QStyledItemDelegate.__init__(self, parent)
  81.  
  82.     def createEditor(self, parent, option, index):
  83.         editor = MyButtonEdit(parent)
  84.         editor.setAutoFillBackground(True)
  85.         editor.installEventFilter(self)
  86.         return editor
  87.  
  88.     def updateEditorGeometry(self, editor, option, index):
  89.         editor.setGeometry(option.rect)
  90.  
  91.     def setEditorData(self, editor, index):
  92.         editor.line_edit.setText(index.model().data(index, Qt.EditRole))
  93.  
  94.     def setModelData(self, editor, model, index):
  95.         model.setData(index, editor.line_edit.text())
  96.  
  97.  
  98. class MyModel(QtCore.QAbstractTableModel):
  99.  
  100.     class Person:
  101.         def __init__(self, f_name, l_name):
  102.             self.f_name = f_name
  103.             self.l_name = l_name
  104.  
  105.     def __init__(self, parent):
  106.         super().__init__(parent)
  107.         self.rows = [MyModel.Person('Joe', 'Smith'), MyModel.Person('Mary', 'Dow')]
  108.         self.columns = ['f_name', 'l_name']
  109.  
  110.     def columnCount(self, index):
  111.         return len(self.columns)
  112.  
  113.     def rowCount(self, index):
  114.         return len(self.rows)
  115.  
  116.     def flags(self, index):
  117.         Qt = QtCore.Qt
  118.         if index.isValid():
  119.             return Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable
  120.  
  121.     def data(self, index, role):
  122.         if role == QtCore.Qt.EditRole or role == QtCore.Qt.DisplayRole:
  123.             attr_name = self.columns[index.column()]
  124.             person = self.rows[index.row()]
  125.             return getattr(person, attr_name)
  126.  
  127.     def setData(self, index, value, role=Qt.EditRole):
  128.         if index.isValid() and role == Qt.EditRole:
  129.             field_name = self.columns[index.column()]
  130.             row = self.rows[index.row()]
  131.             setattr(row, field_name, value)
  132.             self.dataChanged.emit(index, index)
  133.             return True
  134.  
  135.  
  136. class MyWin(QtGui.QDialog):
  137.  
  138.     def __init__(self):
  139.         super().__init__()
  140.         model = MyModel(self)
  141.  
  142.         mapper = QtGui.QDataWidgetMapper(self)
  143.         mapper.setSubmitPolicy(QtGui.QDataWidgetMapper.AutoSubmit)
  144.         mapper.setModel(model)
  145.         mapper.setItemDelegate(MyDelegate(self))
  146.  
  147.         lay = QtGui.QVBoxLayout(self)
  148.  
  149.         table_view = QtGui.QTableView(self)
  150.         table_view.setModel(model)
  151.         table_view.setItemDelegateForColumn(0, MyDelegate(self))
  152.         table_view.setItemDelegateForColumn(1, MyDelegate(self))
  153.  
  154.         ed_f_name = MyButtonEdit(self)
  155.         ed_l_name = MyButtonEdit(self)
  156.  
  157.         lay.addWidget(table_view)
  158.         lay.addWidget(ed_f_name)
  159.         lay.addWidget(ed_l_name)
  160.  
  161.         mapper.addMapping(ed_f_name, 0)
  162.         mapper.addMapping(ed_l_name, 1)
  163.         mapper.toFirst()
  164.  
  165.  
  166. if __name__ == '__main__':
  167.     app = QtGui.QApplication(sys.argv)
  168.     win = MyWin()
  169.     win.show()
  170.     sys.exit(app.exec_())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement