首页 > 其他 > 详细

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

时间:2020-10-06 13:40:13      阅读:279      评论:0      收藏:0      [点我收藏+]

原理:使用三张表进行堆叠,在水平或者垂直滑动条的值发生变化时改变这三张表的堆叠顺序,使用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++实现也是通过该原理实现,有兴趣的可以尝试写一下。

 

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

原文:https://www.cnblogs.com/shi-win-snoopy/p/13772858.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!