本文通过将创建自定义模型保存船只数据,并会用两个不同的表格视图形式来显示同样的模型。
实现自定义模型,继承QAbstractTableModel,具体参照QT库。
/home/yrd/eric_workspace/chap14/ships_model/ships.py
#!/usr/bin/env python3
import platform
from PyQt5.QtCore import (QAbstractTableModel, QDataStream, QFile,
QIODevice, QModelIndex,QVariant, Qt,pyqtSignal)
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QApplication
NAME, OWNER, COUNTRY, DESCRIPTION, TEU = range(5)
MAGIC_NUMBER = 0x570C4
FILE_VERSION = 1
class Ship(object):
def __init__(self, name, owner, country, teu=0, description=""):
self.name = name
self.owner = owner
self.country = country
self.teu = teu
self.description = description
def __hash__(self):
return super(Ship, self).__hash__()
def __lt__(self, other):
return bool(self.name.lower()<other.name.lower())
def __eq__(self, other):
return bool(self.name.lower()==other.name.lower())
class ShipTableModel(QAbstractTableModel):
dataChanged = pyqtSignal(QModelIndex,QModelIndex)
def __init__(self, filename=""):
super(ShipTableModel, self).__init__()
self.filename = filename
self.dirty = False
self.ships = []
self.owners = set()
self.countries = set()
def sortByName(self):
self.beginResetModel()
self.ships = sorted(self.ships)
self.endResetModel()
def sortByCountryOwner(self):
self.beginResetModel()
self.ships = sorted(self.ships,
key=lambda x: (x.country, x.owner, x.name))
self.endResetModel()
def flags(self, index):
if not index.isValid():
return Qt.ItemIsEnabled
return Qt.ItemFlags(
QAbstractTableModel.flags(self, index)|
Qt.ItemIsEditable)
def data(self, index, role=Qt.DisplayRole):
if (not index.isValid() or
not (0 <= index.row() < len(self.ships))):
return QVariant()
ship = self.ships[index.row()]
column = index.column()
if role == Qt.DisplayRole:
if column == NAME:
return ship.name
elif column == OWNER:
return ship.owner
elif column == COUNTRY:
return ship.country
elif column == DESCRIPTION:
return ship.description
elif column == TEU:
return ship.teu
elif role == Qt.TextAlignmentRole:
if column == TEU:
return QVariant(int(Qt.AlignRight|Qt.AlignVCenter))
return QVariant(int(Qt.AlignLeft|Qt.AlignVCenter))
elif role == Qt.TextColorRole and column == TEU:
if ship.teu < 80000:
return QVariant(QColor(Qt.black))
elif ship.teu < 100000:
return QVariant(QColor(Qt.darkBlue))
elif ship.teu < 120000:
return QVariant(QColor(Qt.blue))
else:
return QVariant(QColor(Qt.red))
elif role == Qt.BackgroundColorRole:
if ship.country in ("Bahamas", "Cyprus", "Denmark",
"France", "Germany", "Greece"):
return QVariant(QColor(250, 230, 250))
elif ship.country in ("Hong Kong", "Japan", "Taiwan"):
return QVariant(QColor(250, 250, 230))
elif ship.country in ("Marshall Islands",):
return QVariant(QColor(230, 250, 250))
else:
return QVariant(QColor(210, 230, 230))
return QVariant()
def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.TextAlignmentRole:
if orientation == Qt.Horizontal:
return QVariant(int(Qt.AlignLeft|Qt.AlignVCenter))
return QVariant(int(Qt.AlignRight|Qt.AlignVCenter))
if role != Qt.DisplayRole:
return QVariant()
if orientation == Qt.Horizontal:
if section == NAME:
return QVariant("Name")
elif section == OWNER:
return QVariant("Owner")
elif section == COUNTRY:
return QVariant("Country")
elif section == DESCRIPTION:
return QVariant("Description")
elif section == TEU:
return QVariant("TEU")
return QVariant(int(section + 1))
def rowCount(self, index=QModelIndex()):
return len(self.ships)
def columnCount(self, index=QModelIndex()):
return 5
def setData(self, index, value, role=Qt.EditRole):
if index.isValid() and 0 <= index.row() < len(self.ships):
#self.beginResetModel()
ship = self.ships[index.row()]
column = index.column()
if column == NAME:
ship.name = str(value)
elif column == OWNER:
ship.owner = str(value)
elif column == COUNTRY:
ship.country = str(value)
elif column == DESCRIPTION:
ship.description = str(value)
elif column == TEU:
if str(value).isdecimal():
ship.teu=int(value)
self.dirty = True
self.dataChanged[QModelIndex,QModelIndex].emit(index,index)
#self.endResetModel()
return True
return False
def insertRows(self, position, rows=1, index=QModelIndex