1. 程式人生 > 實用技巧 >Pyqt5——帶圖示的表格(Model/View)

Pyqt5——帶圖示的表格(Model/View)

  需求:表格中第一列內容為學生學號,為了突出學號的表示,在第一列的學號旁增加學號圖示。

  實現:(1)使用Qt的model-view模式生成表格檢視。

     (2)重寫代理(QAbstractItemDelegate)。

  表格樣式如下圖所示。

  程式碼塊。

  Model部分:

class MyTableModel(QAbstractTableModel):
    """Model"""
    def __init__(self):
        super(MyTableModel, self).__init__()
        self._data = []
        self._background_color 
= [] self._headers = ['學號', '姓名', '性別', '年齡'] self._generate_data() def _generate_data(self): """填充表格資料""" name_list = ['張三', '李四', '王五', '王小二', '李美麗', '王二狗'] for id_num, name in enumerate(name_list): self._data.append([str(id_num), name, '
', str(random.randint(20, 25))]) # :預設單元格顏色為白色 self._background_color.append([QColor(255, 255, 255) for i in range(4)]) def rowCount(self, parent=QModelIndex()): """返回行數量。""" return len(self._data) def columnCount(self, parent=QModelIndex()):
"""返回列數量。""" return len(self._headers) def headerData(self, section, orientation, role): """設定表格頭""" if role == Qt.DisplayRole and orientation == Qt.Horizontal: return self._headers[section] def data(self, index, role): """顯示錶格中的資料。""" if not index.isValid() or not 0 <= index.row() < self.rowCount(): return QVariant() row = index.row() col = index.column() if role == Qt.DisplayRole: return self._data[row][col] elif role == Qt.BackgroundColorRole: return self._background_color[row][col] elif role == Qt.TextAlignmentRole: return Qt.AlignCenter return QVariant()

  Delegate部分:

class MyDelegate(QAbstractItemDelegate):
    """Delegate"""
    def __init__(self):
        super(MyDelegate, self).__init__()

    def paint(self, painter, option, index):
        """繪製單元格。"""
        if index.column() == 0:
            # :表格第一列是ID,單元格中繪製一個圖片和ID。
            p = QStyleOptionViewItem()
            p.index = index
            p.rect = option.rect
            p.features = QStyleOptionViewItem.HasDecoration | QStyleOptionViewItem.HasDisplay
            p.text = str(index.data())
            p.decorationSize = QSize(44, 44)      # 設定裝飾圖示的大小。
            p.icon = QIcon('../image/id.png')     # 設定裝飾圖示路徑名
            p.state = option.state
            p.showDecorationSelected = True     # 開啟選中時,單元格高亮顯示
            # :若專案被選擇,則高亮繪製其矩形
            #if p.state & QStyle.State_Selected:
                #painter.fillRect(option.rect, option.palette.highlight())

            p.decorationPosition = QStyleOptionViewItem.Left        # 圖片在文字的左邊
            p.displayAlignment = Qt.AlignLeft | Qt.AlignCenter      # 設定文字的位置
            QApplication.style().drawControl(QStyle.CE_ItemViewItem, p, painter)
        else:
            # :向表格中渲染資料,如果缺少下面程式碼,表格中資料不能正常顯示。
            # :這裡應該在model的data函式之後呼叫,此時通過index可以獲取要顯示。
            # :的資料。
            p = QStyleOptionViewItem()
            p.features = QStyleOptionViewItem.HasDisplay
            p.index = index                     # 表格QModelIndex索引
            p.rect = option.rect
            p.state = option.state

            p.showDecorationSelected = True     # 開啟選中時,單元格高亮顯示
            p.text = str(index.data())          # 表格中的資料
            QApplication.style().drawControl(QStyle.CE_ItemViewItem, p, painter)

完整程式碼檢視:https://gitee.com/cui_zhen/pyqt5-example.git