• 使用pyqt实现官方例子QTableView的冻结行列


    原理:使用三张表进行堆叠,在水平或者垂直滑动条的值发生变化时改变这三张表的堆叠顺序,使用stackUnder()进行堆叠顺序的改变

    直接撸代码:

      1 import typing
      2 from PyQt5 import QtCore, QtGui
      3 from PyQt5.QtWidgets import QTableView, QAbstractItemView, QHeaderView, QAbstractSlider
      4 from PyQt5.QtCore import Qt, QModelIndex
      5 
      6 
      7 class FreezeTableView(QTableView, QAbstractSlider):
      8 
      9     def __init__(self, model):
     10         super(FreezeTableView, self).__init__()
     11         self.model = model
     12         self.frozenTableView = QTableView(self)
     13         self.horizontalView = QTableView(self)
     14         self.up = True
     15 
     16     def init(self):
     17         self.setModel(self.model)
     18         self.frozenTableInit()
     19         self.horizontalViewInit()
     20 
     21         self.horizontalHeader().sectionResized.connect(self.updateSectionWidth)
     22         self.verticalHeader().sectionResized.connect(self.updateSectionHeight)
     23         self.verticalScrollBar().valueChanged.connect(self.vConnectFV)
     24         self.frozenTableView.verticalScrollBar().valueChanged.connect(self.fVConnectV)
     25         self.horizontalScrollBar().valueChanged.connect(self.hConnectH)
     26 
     27     def vConnectFV(self, a0: int):
     28         self.viewport().stackUnder(self.frozenTableView)
     29         self.frozenTableView.stackUnder(self.horizontalView)
     30         self.frozenTableView.verticalScrollBar().setValue(a0)
     31 
     32     def fVConnectV(self, a0: int):
     33         self.viewport().stackUnder(self.frozenTableView)
     34         self.frozenTableView.stackUnder(self.horizontalView)
     35         self.verticalScrollBar().setValue(a0)
     36 
     37     def hConnectH(self, a0: int):
     38         self.viewport().stackUnder(self.horizontalView)
     39         self.horizontalView.stackUnder(self.frozenTableView)
     40         self.horizontalView.horizontalScrollBar().setValue(a0)
     41 
     42     def frozenTableInit(self):
     43         self.frozenTableView.setModel(self.model)
     44         self.frozenTableView.verticalHeader().hide()
     45         self.frozenTableView.setFocusPolicy(Qt.NoFocus)
     46         self.frozenTableView.horizontalHeader().setFixedHeight(self.horizontalHeader().height())
     47         self.frozenTableView.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed)
     48 
     49         self.viewport().stackUnder(self.frozenTableView)
     50         self.frozenTableView.setStyleSheet('QTableView {'
     51                                            'border: none;'
     52                                            'background-color: #8EDE21;'
     53                                            'selection-background-color: #999}')
     54         self.frozenTableView.setSelectionModel(self.selectionModel())
     55         [self.frozenTableView.setColumnHidden(col, True) for col in range(1, self.model.columnCount())]
     56         self.frozenTableView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     57         self.frozenTableView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     58         self.frozenTableView.show()
     59 
     60         self.updateFrozenTableGeometry()
     61         self.frozenTableView.setVerticalScrollMode(self.ScrollPerPixel)
     62         self.setVerticalScrollMode(self.ScrollPerPixel)
     63         self.setHorizontalScrollMode(self.ScrollPerPixel)
     64 
     65     def horizontalViewInit(self):
     66         self.horizontalView.setModel(self.model)
     67         self.horizontalView.horizontalHeader().hide()
     68         self.horizontalView.setFocusPolicy(Qt.NoFocus)
     69         self.horizontalView.verticalHeader().setFixedWidth(self.verticalHeader().width())
     70         self.horizontalView.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
     71 
     72         self.frozenTableView.stackUnder(self.horizontalView)
     73         self.horizontalView.setStyleSheet('QTableView { border: none;'
     74                                           'background-color: #8EDE21;'
     75                                           'selection-background-color: #999}')
     76         self.horizontalView.setSelectionModel(self.selectionModel())
     77         [self.horizontalView.setRowHidden(row, True) for row in range(1, self.model.rowCount())]
     78         self.horizontalView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     79         self.horizontalView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
     80         self.horizontalView.show()
     81 
     82         self.updateFrozenTableGeometry()
     83         self.horizontalView.setHorizontalScrollMode(self.ScrollPerPixel)
     84 
     85     def updateFrozenTableGeometry(self):
     86         self.frozenTableView.setGeometry(self.verticalHeader().width() + self.frameWidth(),
     87                                          self.frameWidth(), self.columnWidth(0),
     88                                          self.viewport().height() + self.horizontalHeader().height())
     89         self.horizontalView.setGeometry(self.frameWidth(), self.frameWidth() + self.horizontalHeader().height(),
     90                                         self.viewport().width() + self.verticalHeader().width(), self.rowHeight(0))
     91 
     92     def updateSectionWidth(self, logicalIndex, oldSize, newSize):
     93         self.horizontalView.setColumnWidth(logicalIndex, newSize)
     94         if not logicalIndex:
     95             self.frozenTableView.setColumnWidth(0, newSize)
     96         self.updateFrozenTableGeometry()
     97 
     98     def updateSectionHeight(self, logicalIndex, oldSize, newSize):
     99         self.frozenTableView.setRowHeight(logicalIndex, newSize)
    100         if not logicalIndex:
    101             self.horizontalView.setRowHeight(0, newSize)
    102         self.updateFrozenTableGeometry()
    103 
    104     def resizeEvent(self, e: QtGui.QResizeEvent) -> None:
    105         QTableView.resizeEvent(self, e)
    106         self.updateFrozenTableGeometry()
    107 
    108     def scrollTo(self, index: QtCore.QModelIndex, hint: QAbstractItemView.ScrollHint = ...) -> None:
    109         if index.column() > 0 or index.row() > 0:
    110             QTableView.scrollTo(self, index, hint)
    111 
    112     def moveCursor(self, cursorAction: QAbstractItemView.CursorAction,
    113                    modifiers: typing.Union[QtCore.Qt.KeyboardModifiers,
    114                                            QtCore.Qt.KeyboardModifier]) -> QtCore.QModelIndex:
    115         current = QTableView.moveCursor(self, cursorAction, modifiers)
    116         if cursorAction == QAbstractItemView.MoveLeft and current.column() > 0 
    117                 and self.visualRect(current).topLeft().x() < self.frozenTableView.columnWidth(0):
    118             newValue = self.verticalScrollBar().value() + self.visualRect(current).topLeft().x() 
    119                        - self.frozenTableView.columnWidth(0)
    120             self.horizontalScrollBar().setValue(newValue)
    121         if cursorAction == QAbstractItemView.MoveUp and current.row() > 0 
    122                 and self.visualRect(current).topLeft().y() < self.horizontalView.rowHeight(0):
    123             newValue = self.horizontalScrollBar().value() + self.visualRect(current).topLeft().y() 
    124                        - self.horizontalView.rowHeight(0)
    125             self.verticalScrollBar().setValue(newValue)
    126 
    127         return current

    具体完整代码,可以给git clone https://github.com/llkid/freezeWidget.git,c++实现也是通过该原理实现,有兴趣的可以尝试写一下。

  • 相关阅读:
    SequenceInputStream
    BufferedReader
    FileWriter
    FileReader
    BufferedOutputStream
    javascript/html 禁止图片缓存
    localStorage util
    FormData上传文件 带进度条
    javascript 一些函数的实现 Function.prototype.bind, Array.prototype.map
    替代jquery中的几个函数
  • 原文地址:https://www.cnblogs.com/shi-win-snoopy/p/13772858.html
Copyright © 2020-2023  润新知