PyQt’s Model/View Framework -- A Quick...

72
Chen Chun-Chia PYQT’S MODEL/VIEW FRAMEWORK -- A QUICK OVERVIEW

Transcript of PyQt’s Model/View Framework -- A Quick...

Page 1: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Chen Chun-Chia

PYQT’S MODEL/VIEW FRAMEWORK -- A QUICK OVERVIEW

Page 2: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt / PyQt / PySide

Qt

PyQt / PyKDE

PySide

1995 2000 2005 2010

1.0

2.0

2.0 3.0 4.0

3.0 4.0

1.0 1.0.8

4.8.5

4.7.4

Page 3: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

A Simple PyQt App

import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv) sys.exit(app.exec_())

Your GUI Widgets

Page 4: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

A Simple PyQt App

import sys from PyQt4.QtGui import * from PyQt4.QtCore import * app = QApplication(sys.argv) sys.exit(app.exec_())

Your GUI Widgets

OR Not Recommend

Page 5: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

A Simple PyQt App – Example

import sys from PyQt4.QtGui import * from PyQt4.QtCore import * app = QApplication(sys.argv) sys.exit(app.exec_())

win = QWidget() win.show()

Page 6: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Customize Widget

class AWidget(QWidget): def __init__(self, parent=None):

or any other widget you want ↙

Page 7: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Customize Widget ~ super.__init__

class AWidget(QWidget): def __init__(self, parent=None): super(AWidget, self).__init__(parent)

↖ remember to call superclass.__init__()

Page 8: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Customize Widget ~ more Fields / Methods

class AWidget(QWidget): def __init__(self, parent=None): super(AWidget, self).__init__(parent) self.a_field = ... def a_method(self, ...): ...

Page 9: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Customize Widget ~ Show

class AWidget(QWidget): def __init__(self, parent=None): super(AWidget, self).__init__(parent) self.a_field = ... def a_method(self, ...): ...

app = QApplication(sys.argv) win = AWidget() win.show() sys.exit(app.exec_())

Page 10: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Model / View Architecture

Data

Model

View

Rendering

Page 11: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Model / View Architecture with Delegate

Data

Model

View

Rendering

Rendering

Editing

Delegate

Page 12: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Display Data

Data

Model

View

Rendering

Rendering

Editing

Delegate

Page 13: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Example ~ A List

Data

Model

View

data = [70, 90, 20, 50]

Delegate

Page 14: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build List Model class MyListModel(QAbstractListModel): def __init__(self, parent=None): def rowCount(self, parent=QModelIndex()): def data(self, index, role=Qt.DisplayRole): Data

View

Delegate

Model

Page 15: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build List Model class MyListModel(QAbstractListModel): def __init__(self, parent=None): super(MyListModel, self).__init__(parent) self._data = [70, 90, 20, 50] def rowCount(self, parent=QModelIndex()): def data(self, index, role=Qt.DisplayRole): Data

View

Delegate

Model

Page 16: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build List Model ~ rowCount class MyListModel(QAbstractListModel): def __init__(self, parent=None): super(MyListModel, self).__init__(parent) self._data = [70, 90, 20, 50] def rowCount(self, parent=QModelIndex()): return len(self._data) def data(self, index, role=Qt.DisplayRole):

[int]

Data

View

Delegate

Model

Page 17: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build List Model ~ data class MyListModel(QAbstractListModel): def __init__(self, parent=None): super(MyListModel, self).__init__(parent) self._data = [70, 90, 20, 50] def rowCount(self, parent=QModelIndex()): return len(self._data) def data(self, index, role=Qt.DisplayRole): if not index.isValid() or \ not 0 <= index.row() < self.rowCount(): return QVariant() row = index.row() if role == Qt.DisplayRole: return str(self._data[row]) return QVariant()

[str / QString]

Data

View

Delegate

Model

Page 18: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Show List View app = QApplication(sys.argv) model = MyListModel() view = QListView() view.setModel(model) view.show() sys.exit(app.exec_())

Data

Delegate

Model

View

Page 19: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Display Data with Roles class MyListModel(QAbstractListModel): def __init__(self, parent=None): super(MyListModel, self).__init__(parent) self._data = [70, 90, 20, 50] def rowCount(self, parent=QModelIndex()): return len(self._data) def data(self, index, role=Qt.DisplayRole): if not index.isValid() or \ not 0 <= index.row() < self.rowCount(): return QVariant() row = index.row() if role == Qt.DisplayRole: return str(self._data[row]) return QVariant()

Page 20: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.ItemDataRole • General purpose roles

• Qt.DisplayRole Text of the item (QString) • Qt.DecorationRole Icon of the item (QColor, QIcon or QPixmap) • Qt.EditRole Editing data for editor (QString) • Qt.ToolTipRole Tooltip of the item (QString) • Qt.StatusTipRole Text in the status bar (QString) • Qt.WhatsThisRole Text in "What's This?" mode (QString) • Qt.SizeHintRole Size hint in view (QSize)

Page 21: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.ItemDataRole (More...) • Roles describing appearance and meta data:

• Qt.FontRole Font of the item (QFont) • Qt.TextAlignmentRole Text alignment of the item (Qt.AlignmentFlag) • Qt.BackgroundRole Background of the item (QBrush) • Qt.ForegroundRole Foreground of the item (QBrush) • Qt.CheckStateRole Checked state of the item (Qt.CheckState)

• Accessibility roles: • Qt.AccessibleTextRole Text for accessibility (QString) • Qt.AccessibleDescriptionRole Description for accessibility (QString)

• User roles: • Qt.UserRole 1st role for specific purposes

Page 22: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.DecorationRole • General purpose roles

• Qt.DisplayRole Text of the item (QString) • Qt.DecorationRole Icon of the item (QColor, QIcon or QPixmap) • Qt.EditRole Editing data for editor (QString) • Qt.ToolTipRole Tooltip of the item (QString) • Qt.StatusTipRole Text in the status bar (QString) • Qt.WhatsThisRole Text in "What's This?" mode (QString) • Qt.SizeHintRole Size hint in view (QSize)

Page 23: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.ToolTipRole • General purpose roles

• Qt.DisplayRole Text of the item (QString) • Qt.DecorationRole Icon of the item (QColor, QIcon or QPixmap) • Qt.EditRole Editing data for editor (QString) • Qt.ToolTipRole Tooltip of the item (QString) • Qt.StatusTipRole Text in the status bar (QString) • Qt.WhatsThisRole Text in "What's This?" mode (QString) • Qt.SizeHintRole Size hint in view (QSize)

Page 24: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.TextAlignmentRole • Roles describing appearance and meta data:

• Qt.FontRole Font of the item (QFont) • Qt.TextAlignmentRole Text alignment of the item (Qt.AlignmentFlag) • Qt.BackgroundRole Background of the item (QBrush) • Qt.ForegroundRole Foreground of the item (QBrush) • Qt.CheckStateRole Checked state of the item (Qt.CheckState)

• Accessibility roles: • Qt.AccessibleTextRole Text for accessibility (QString) • Qt.AccessibleDescriptionRole Description for accessibility (QString)

• User roles: • Qt.UserRole 1st role for specific purposes

Page 25: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.BackgroundRole • Roles describing appearance and meta data:

• Qt.FontRole Font of the item (QFont) • Qt.TextAlignmentRole Text alignment of the item (Qt.AlignmentFlag) • Qt.BackgroundRole Background of the item (QBrush) • Qt.ForegroundRole Foreground of the item (QBrush) • Qt.CheckStateRole Checked state of the item (Qt.CheckState)

• Accessibility roles: • Qt.AccessibleTextRole Text for accessibility (QString) • Qt.AccessibleDescriptionRole Description for accessibility (QString)

• User roles: • Qt.UserRole 1st role for specific purposes

Page 26: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.ForegroundRole • Roles describing appearance and meta data:

• Qt.FontRole Font of the item (QFont) • Qt.TextAlignmentRole Text alignment of the item (Qt.AlignmentFlag) • Qt.BackgroundRole Background of the item (QBrush) • Qt.ForegroundRole Foreground of the item (QBrush) • Qt.CheckStateRole Checked state of the item (Qt.CheckState)

• Accessibility roles: • Qt.AccessibleTextRole Text for accessibility (QString) • Qt.AccessibleDescriptionRole Description for accessibility (QString)

• User roles: • Qt.UserRole 1st role for specific purposes

Page 27: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.CheckStateRole • Roles describing appearance and meta data:

• Qt.FontRole Font of the item (QFont) • Qt.TextAlignmentRole Text alignment of the item (Qt.AlignmentFlag) • Qt.BackgroundRole Background of the item (QBrush) • Qt.ForegroundRole Foreground of the item (QBrush) • Qt.CheckStateRole Checked state of the item (Qt.CheckState)

• Accessibility roles: • Qt.AccessibleTextRole Text for accessibility (QString) • Qt.AccessibleDescriptionRole Description for accessibility (QString)

• User roles: • Qt.UserRole 1st role for specific purposes

Page 28: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Qt.UserRole • Roles describing appearance and meta data:

• Qt.FontRole Font of the item (QFont) • Qt.TextAlignmentRole Text alignment of the item (Qt.AlignmentFlag) • Qt.BackgroundRole Background of the item (QBrush) • Qt.ForegroundRole Foreground of the item (QBrush) • Qt.CheckStateRole Checked state of the item (Qt.CheckState)

• Accessibility roles: • Qt.AccessibleTextRole Text for accessibility (QString) • Qt.AccessibleDescriptionRole Description for accessibility (QString)

• User roles: • Qt.UserRole 1st role for specific purposes

↖ UserRole, UserRole+1, UserRole+2, ...

For user roles, it is up to the developer to decide which types to use and ensure that components use the correct types when accessing and setting data.

Page 29: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Display Data with Delegate

View Rendering

Editing

Delegate

Data

Model

Rendering

Page 30: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Item Delegate ~ paint class MyDelegate(QStyledItemDelegate): def paint(self, painter, option, index):

Data

Model

View

Delegate

Page 31: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Item Delegate ~ Get Model Data class MyDelegate(QStyledItemDelegate): def paint(self, painter, option, index): item_var = index.data(Qt.DisplayRole) item_str = item_var.toPyObject() opts = QStyleOptionProgressBarV2() opts.rect = option.rect opts.minimum = 0 opts.maximum = 100 opts.text = item_str opts.textAlignment = Qt.AlignCenter opts.textVisible = True opts.progress = int(item_str) QApplication.style().drawControl( QStyle.CE_ProgressBar, opts, painter)

Data

Model

View

Delegate

[QVariant]

Page 32: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Item Delegate ~ Trans to Python Type class MyDelegate(QStyledItemDelegate): def paint(self, painter, option, index): item_var = index.data(Qt.DisplayRole) item_str = item_var.toPyObject() opts = QStyleOptionProgressBarV2() opts.rect = option.rect opts.minimum = 0 opts.maximum = 100 opts.text = item_str opts.textAlignment = Qt.AlignCenter opts.textVisible = True opts.progress = int(item_str) QApplication.style().drawControl( QStyle.CE_ProgressBar, opts, painter)

Data

Model

View

Delegate

[Python Type of Item]

Page 33: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Item Delegate ~ Draw Control class MyDelegate(QStyledItemDelegate): def paint(self, painter, option, index): item_var = index.data(Qt.DisplayRole) item_str = item_var.toPyObject() opts = QStyleOptionProgressBarV2() opts.rect = option.rect opts.minimum = 0 opts.maximum = 100 opts.text = item_str opts.textAlignment = Qt.AlignCenter opts.textVisible = True opts.progress = int(item_str) QApplication.style().drawControl( QStyle.CE_ProgressBar, opts, painter)

Data

Model

View

Delegate

Draw Progress Bar

Page 34: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Set Delegate into View app = QApplication(sys.argv) model = MyListModel() delegate = MyDelegate() view = QListView() view.setModel(model) view.setItemDelegate(delegate) view.show() sys.exit(app.exec_())

Data

Model

View

Delegate

Page 35: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Edit Data Use Default Editor = QLineEdit

Data

Model

View

Rendering

Rendering

Editing

Delegate

Page 36: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Activate Default Editor class MyListModel(QAbstractListModel): def flags(self, index): flag = super(MyListModel, self).flags(index) return flag | Qt.ItemIsEditable

Data

View

Model

Delegate

Page 37: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Activate Default Editor class MyListModel(QAbstractListModel): def flags(self, index): flag = super(MyListModel, self).flags(index) return flag | Qt.ItemIsEditable

Data

View

Model

Delegate

Page 38: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Activate Default Editor class MyListModel(QAbstractListModel): def flags(self, index): flag = super(MyListModel, self).flags(index) return flag | Qt.ItemIsEditable

Data

View

Model

? ?

empty

not change

Delegate

Page 39: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Load Model Data to Editor class MyListModel(QAbstractListModel): def data(self, index, role=Qt.DisplayRole): ... elif role == Qt.EditRole: return str(self._data[row]) ...

View

Model

Data

Delegate

Page 40: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Load Model Data to Editor class MyListModel(QAbstractListModel): def data(self, index, role=Qt.DisplayRole): ... elif role == Qt.EditRole: return str(self._data[row]) ...

View

Model

Data

✔ ?

good

still not change ...

Delegate

Page 41: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

After Editing ~ Set Data to Model class MyListModel(QAbstractListModel): def setData(self, index, value, role=Qt.EditRole): ... if role == Qt.EditRole: value_int, ok = value.toInt() if ok: self._data[row] = value_int self.dataChanged.emit(index, index) return True return False ...

Model

Data

Delegate

View

Page 42: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

After Editing ~ Set Data to Model class MyListModel(QAbstractListModel): def setData(self, index, value, role=Qt.EditRole): ... if role == Qt.EditRole: value_int, ok = value.toInt() if ok: self._data[row] = value_int self.dataChanged.emit(index, index) return True return False ...

[QVariant → int]

Model

Data

Delegate

View

Page 43: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

After Editing ~ Set Data to Model class MyListModel(QAbstractListModel): def setData(self, index, value, role=Qt.EditRole): ... if role == Qt.EditRole: value_int, ok = value.toInt() if ok: self._data[row] = value_int self.dataChanged.emit(index, index) return True return False ...

Update internal data ↙

Model

Data

Delegate

View

Page 44: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

After Editing ~ Set Data to Model class MyListModel(QAbstractListModel): def setData(self, index, value, role=Qt.EditRole): ... if role == Qt.EditRole: value_int, ok = value.toInt() if ok: self._data[row] = value_int self.dataChanged.emit(index, index) return True return False ...

↖ Notify view that data have changed

Model

Data

Delegate

View

Page 45: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

After Editing ~ Set Data to Model class MyListModel(QAbstractListModel): def setData(self, index, value, role=Qt.EditRole): ... if role == Qt.EditRole: value_int, ok = value.toInt() if ok: self._data[row] = value_int self.dataChanged.emit(index, index) return True return False ...

↖ Return whether data have successfully set or not

Model

Data

Delegate

View

Page 46: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Edit Data with Default Editor

Model

View

Data

✔ ✔

good

it changed

Delegate

Page 47: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Edit Data with Default Editor

Model

View

Data

Model.data

Model.flags

Delegate

Page 48: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Edit Data with Default Editor

Model

View

Data

Model.setData

Model.flags

Model.data

Delegate

Page 49: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Edit Data with Delegate

Data

Model

View

Rendering

Editing

Delegate

Rendering

Page 50: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Recall : Default Editor

Model.flags

Model.data Model.setData

Page 51: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Recall : Default Editor Create editor ↙

Model.flags

Model.data Model.setData

Set editor data ↙ Set model data

Page 52: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Edit Delegate class MyEditDelegate(QStyledItemDelegate): def createEditor(self, parent, option, index): def setEditorData(self, editor, index): def setModelData(self, editor, model, index):

Data

Model

View

Delegate

Page 53: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Edit Delegate ~ createEditor class MyEditDelegate(QStyledItemDelegate): def createEditor(self, parent, option, index): sbox = QSpinBox(parent) sbox.setRange(0, 100) return sbox def setEditorData(self, editor, index): def setModelData(self, editor, model, index):

↖ ← Create editor ... and return itself

Data

Model

View

Delegate

Page 54: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Edit Delegate ~ setEditorData class MyEditDelegate(QStyledItemDelegate): def createEditor(self, parent, option, index): sbox = QSpinBox(parent) sbox.setRange(0, 100) return sbox def setEditorData(self, editor, index): item_var = index.data(Qt.DisplayRole) item_str = item_var.toPyObject() item_int = int(item_str) editor.setValue(item_int) def setModelData(self, editor, model, index):

← Set editor data

View

Delegate

Model

Data

Page 55: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Build Edit Delegate ~ setModelData class MyEditDelegate(QStyledItemDelegate): def createEditor(self, parent, option, index): sbox = QSpinBox(parent) sbox.setRange(0, 100) return sbox def setEditorData(self, editor, index): item_var = index.data(Qt.DisplayRole) item_str = item_var.toPyObject() item_int = int(item_str) editor.setValue(item_int) def setModelData(self, editor, model, index): data_int = editor.value() data_var = QVariant(data_int) model.setData(index, data_var)

↖ Set model data

View

Delegate

Model

Data

Page 56: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Set Delegate into View app = QApplication(sys.argv) model = MyListModel() delegate = MyEditDelegate() view = QListView() view.setModel(model) view.setItemDelegate(delegate) view.show() sys.exit(app.exec_())

Data

Model

View

Delegate

Page 57: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Edit Data with Delegate

Model

Delegate

View

Data

← QSpinBox ↙

Page 58: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Sort ? Filter ? Use QSortFilterProxyModel

Data

Model

View

Proxy Model

Rendering

Editing

Delegate

Page 59: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Sort Data ~ QSortFilterProxyModel

Data

Model

View

Proxy Model

class SortProxyModel(QSortFilterProxyModel): def lessThan(self, left_index, right_index):

Page 60: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Sort Data ~ QSortFilterProxyModel

Data

Model

View

Proxy Model

class SortProxyModel(QSortFilterProxyModel): def lessThan(self, left_index, right_index): left_var = left_index.data(Qt.DisplayRole) right_var = right_index.data(Qt.DisplayRole) left_str = left_var.toPyObject() right_str = right_var.toPyObject() left_int = int(left_str) right_int = int(right_str) return (left_int < right_int)

↖ return True or False

Page 61: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Apply SortProxyModel to Model and View

Proxy Model

app = QApplication(sys.argv) model = MyListModel() proxy = SortProxyModel() proxy.setSourceModel(model) proxy.sort(0) view = QListView() view.setModel(proxy) view.show() sys.exit(app.exec_())

View

Model

Data

← Sort data by column 0

Page 62: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Sort Data

Proxy Model

View

Model

Data

↖ Data sorted

Page 63: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Filter Data ~ QSortFilterProxyModel

Data

Model

View

Proxy Model

class FilterProxyModel(QSortFilterProxyModel): def filterAcceptsRow(self, src_row, src_parent):

Page 64: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Filter Data ~ QSortFilterProxyModel

Data

Model

View

Proxy Model

class FilterProxyModel(QSortFilterProxyModel): def filterAcceptsRow(self, src_row, src_parent): src_model = self.sourceModel() src_index = src_model.index(src_row, 0) item_var = src_index.data(Qt.DisplayRole) item_int = int(item_var.toPyObject()) return (item_int >= 60)

↖ return True or False

Page 65: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Apply FilterProxyModel

Proxy Model

app = QApplication(sys.argv) model = MyListModel() proxy = FilterProxyModel() proxy.setSourceModel(model) proxy.setDynamicSortFilter(True) view = QListView() view.setModel(proxy) view.show() sys.exit(app.exec_())

View

Model

Data

↖ If True, data will re-filter when original model is changed

Page 66: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Filter Data

Proxy Model

View

Model

Data

↖ Data filtered

Page 67: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Sort & Filter ~ Recap class ProxyModel(QSortFilterProxyModel): def lessThan(self, left_index, right_index) def filterAcceptsRow(self, src_row, src_parent)

Proxy Model

View

Model

Data

Page 68: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Live DEMO Server Loading Monitor

Server A Server B Server C

Loading % Loading % Loading %

A %

B %

C %

Page 69: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

References • PyQt (Riverbank) http://www.riverbankcomputing.co.uk/

• Qt http://qt.nokia.com/

• PySide http://www.pyside.org/

• Rapid GUI Programming with Python and Qt

• by Mark Summerfield • ISBN: 978-0132354189

• Advanced Qt Programming • by Mark Summerfield • ISBN: 978-0321635907

Page 70: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

References • C++ GUI Programming with Qt 4

• by Jasmin Blanchette and Mark Summerfield • ISBN: 978-0132354165

Page 71: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Q & A

Page 72: PyQt’s Model/View Framework -- A Quick Overviewfiles.meetup.com/2179791/pyqt-model-view-framework-overview.pdf · import sys from PyQt4 import QtGui, QtCore app = QtGui.QApplication(sys.argv)

Contacts • PTT cccx • Plurk ccc_ • Facebook ccc.larc • Google ccc.larc • Email [email protected]

陳俊嘉 a.k.a CCC