如何解决动态自动调整QTableView水平标题高度
我试图让 - --command
- docker run --privileged
在列宽改变时自动调整高度,我已经对 QTableView
进行了子分类,但我无法实际使用它,我正在使用 {每当更改列宽时,{1}} 的 {1}} 信号,并根据新列和列标题的字符串长度,我试图估计高度。
QHeaderView
我实际上不确定我是否走在正确的道路上,试图通过在部分调整大小事件上调用 sectionResized
来更改标题的高度,我一直在寻找 QHeaderView docs 但是我无法弄清楚需要覆盖 QHeaderView
的方法才能完成此操作。
编辑:
我没有手动尝试估计高度,这不是一个好主意,而是使用了 QHeaderView.sectionSizeFromContents
和 from pyside2.QtCore import *
from pyside2.QtWidgets import *
class HeaderView(QHeaderView):
def __init__(self,parent):
super(HeaderView,self).__init__(Qt.Horizontal,parent)
self.setStyleSheet(
"QHeaderView::section{background-color: #ffffff; "
"font-weight: bold; "
"padding-left: 2px; "
"color: #3467ba; "
"border:0px; "
"border-left: 1px solid #ababab; "
"border-bottom: 1px solid gray;}")
self.setStretchLastSection(True)
self.setDefaultAlignment(Qt.AlignCenter|Qt.Alignment(Qt.TextWordWrap))
class TableView(QTableView):
def __init__(self,parent=None):
super(TableView,self).__init__(parent)
self.setAlternatingRowColors(True)
self.setShowGrid(False)
model = DataModel(self)
self.setModel(model)
self.setWordWrap(True)
self._headerView = HeaderView(self)
self._headerView.sectionResized.connect(self.resizeColumns)
self.setHorizontalHeader(self._headerView)
self.resize(800,400)
def resizeColumns(self,idx,oldSize,newSize):
"""
widthEstimation = length of character for header multiplied by 10 for each column
estimatedHeight = (estimatedWidth*10/columnwidth) + 5 for each column (the assumption is (estimatedWidth/columnWidth) gives number of line required for the header text)
"""
widthEstimation = [len(self.model().headerData(colIdx))*10 for colIdx in range(self.model().columnCount())]
estimatedHeight = max(estimatedWidth*10//self.columnWidth(colIdx)+5 for colIdx,estimatedWidth in enumerate(widthEstimation))
self._headerView.setMinimumHeight(estimatedHeight)
class DataModel(QAbstractTableModel):
def __init__(self,parent):
super(DataModel,self).__init__(parent)
#Setting some static data
self._data = [['Dummy-01-0001','M','41.01026694045174','NOT HISPANIC OR LATINO','Albumin (g/L)','N'] for _ in range(5)]+\
[['Dummy-01-0001','F','HISPANIC OR LATINO','Chloride (mmol/L)','Y'] for _ in range(5)]
self._header = ['Unique Subject Identifier (USUBJID)','Sex (SEX)','Age (AGE)','Ethnicity (ETHNIC)','Parameter (ParaM)','Analysis Reference Range Indicator (ANRIND)']
def rowCount(self,parent=None):
return len(self._data)
def columnCount(self,parent=None):
return len(self._header)
def data(self,index,role=Qt.displayRole):
if index.isValid() and role==Qt.displayRole:
return str(self._data[index.row()][index.column()])
def headerData(self,section,orientation:Qt.Horizontal = Qt.Horizontal,role=Qt.displayRole):
if orientation == Qt.Horizontal:
if role == Qt.displayRole:
return self._header[section]
# elif role == Qt.TextAlignmentRole and section==0:
# return Qt.AlignLeft|Qt.Alignment(Qt.TextWordWrap)
def flags(self,index):
if index.isValid():
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
if __name__ == "__main__":
import sys
app = QApplication()
widg = TableView()
widg.show()
sys.exit(app.exec_())
;它给了我比以前更好的结果,但我仍然不确定如何去做。
我尝试将 setMinimumHeight
除以实际的 QHeaderView
,这样可以更好地估计标题字符串所需的行数,将其乘以 fontMetrics()
加上 5 个像素作为偏移量.
sectionSizefromContent
编辑:
我尝试在 Qt 论坛上提问,@SGiast 提出了确定给定列标题的边界矩形的想法,覆盖 sectionSize
的 sectionSizeFromContents
方法;确定每个部分所需的最小宽度和标题所需的最大高度很有帮助:
fontMertircs().height()
该线程在 Qt Forum 处于活动状态
解决方法
最后,通过一些互联网搜索,以及在 @SGiast 的 Qt 论坛上使用 fontMetrics 和从 How to make QTableView to adjust the height of it's horizontal header automatically in PyQt? 确定边界矩形的想法,并在 SO thread: How to use QFontMetrics boundingRect to measure size? 的帮助下,我得到了能够实现所需的行为。
class HeaderView(QHeaderView):
def __init__(self,parent=None):
super().__init__(Qt.Horizontal,parent=parent)
self.setStyleSheet(
"QHeaderView::section{background-color: #ffffff; "
"font-weight: bold; "
"color: #3467ba; "
"border:0px; "
"border-left: 1px solid #ababab; "
"border-bottom: 1px solid gray;}"
)
self.setStretchLastSection(True)
self.setDefaultAlignment(Qt.AlignCenter | Qt.Alignment(Qt.TextWordWrap))
self._setMaxHeight()
def sectionHeight(self,logicalIndex):
return (self.fontMetrics().boundingRect(QRect(0,self.sectionSize(logicalIndex)-10,self._MAXHEIGHT),self.defaultAlignment(),self.model().headerData(logicalIndex))).height()
def _setMaxHeight(self):
self._MAXHEIGHT = max(l.height() for l in (self.fontMetrics().boundingRect(QRect(),self.parent().model().headerData(i)) for i in range(self.parent().model().columnCount())))
class TableView(QTableView):
def __init__(self,parent=None):
super(TableView,self).__init__(parent)
self.setAlternatingRowColors(True)
self.setShowGrid(False)
model = DataModel(self)
self.setModel(model)
self.setWordWrap(True)
self._headerView = HeaderView(self)
self._headerView.sectionResized.connect(self.resizeColumns)
self.setHorizontalHeader(self._headerView)
self.resize(800,400)
self._widths = []
def resizeColumns(self,idx,oldSize,newSize):
minH = min(self._headerView._MAXHEIGHT,max(self._headerView.sectionHeight(i) for i in range(self.model().columnCount())))
self._headerView.setMinimumHeight(minH)
print(minH)
class DataModel(QAbstractTableModel):
def __init__(self,parent):
super(DataModel,self).__init__(parent)
#Setting some static data
self._data = [['Dummy-01-0001','M','41.01026694045174','NOT HISPANIC OR LATINO','Albumin (g/L)','N'] for _ in range(5)]+\
[['Dummy-01-0001','F','HISPANIC OR LATINO','Chloride (mmol/L)','Y'] for _ in range(5)]
self._header = ['Unique Subject Identifier (USUBJID)','Sex (SEX)','Age (AGE)','Ethnicity (ETHNIC)','Parameter (PARAM)','Analysis Reference Range Indicator (ANRIND)']
def rowCount(self,parent=None):
return len(self._data)
def columnCount(self,parent=None):
return len(self._header)
def data(self,index,role=Qt.DisplayRole):
if index.isValid() and role==Qt.DisplayRole:
return str(self._data[index.row()][index.column()])
def headerData(self,section,orientation:Qt.Horizontal = Qt.Horizontal,role=Qt.DisplayRole):
if orientation == Qt.Horizontal:
if role == Qt.DisplayRole:
return self._header[section]
# elif role == Qt.TextAlignmentRole and section==0:
# return Qt.AlignLeft|Qt.Alignment(Qt.TextWordWrap)
def flags(self,index):
if index.isValid():
return Qt.ItemIsEnabled | Qt.ItemIsSelectable
if __name__ == "__main__":
import sys
app = QApplication()
widg = TableView()
widg.show()
sys.exit(app.exec_())
我在 HeaderView
类中创建了两个方法,方法 _setMaxHeight
给出了当每列中的文本具有最大换行时标题最大高度的估计,标题高度将永远不会增加超过这个。
方法 sectionHeight
本质上与 sectionSize
相似,不同之处在于,我创建的方法将使用 width
给出给定列标题的边界矩形的高度由 QHeaderView 的 sectionSize
方法给出,-10 用作偏移量。
我创建的最后一个方法是TableView类中的resizeColumns
,这个方法连接到sectionResized
的{{1}}信号。每次调用此方法时(即调整部分的宽度),它会为每个部分(即列)调用 HeaderView
,并从中取出最大高度,最后将最大值与 { 中的值进行比较{1}} 的 sectionHeight
,以最小值为准,成为 HeaderView 的新的 minimumHeight,因此无论何时更改列宽,标题高度都会无缝调整。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。