使用 PyQt/PySide 禁用 QTableWidget 中特定列中的排序箭头
Posted
技术标签:
【中文标题】使用 PyQt/PySide 禁用 QTableWidget 中特定列中的排序箭头【英文标题】:Disable the sort arrow in a specific column in QTableWidget with PyQt/PySide 【发布时间】:2020-12-18 11:07:11 【问题描述】:我想从第一列标题中删除箭头,以便标题以复选框为中心。所有这些都不会禁用对列进行排序的可能性。
这是我当前的代码。
import sys
from PySide6.QtCore import Qt
from PySide6.QtWidgets import (
QApplication,
QProxyStyle,
QStyle,
QTableWidget,
QTableWidgetItem,
)
class ProxyStyle(QProxyStyle):
def subElementRect(self, e, opt, widget):
r = super().subElementRect(e, opt, widget)
if e == QStyle.SE_ItemViewItemCheckIndicator:
r.moveCenter(opt.rect.center())
return r
class Table(QTableWidget):
def __init__(self):
QTableWidget.__init__(self, 3, 1)
self._style = ProxyStyle(self.style())
self.setStyle(self._style)
for i in range(self.rowCount()):
for j in range(self.columnCount()):
it = QTableWidgetItem()
self.setItem(i, j, it)
it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
it.setCheckState(Qt.Checked if (i + j) % 2 == 0 else Qt.Unchecked)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = Table()
w.show()
sys.exit(app.exec_())
【问题讨论】:
【参考方案1】:最简单的解决方案是覆盖drawControl()
并将QStyleOptionHeader 的indicator
设置为0,如果该列与您要隐藏的列匹配。
class ProxyStyle(QProxyStyle):
# ...
def drawControl(self, ctl, opt, qp, widget=None):
if ctl == QStyle.CE_HeaderSection and opt.orientation == Qt.Horizontal:
if opt.section == widget.parent().property('hideSortIndicatorColumn'):
opt.sortIndicator = 0
super().drawControl(ctl, opt, qp, widget)
class Table(QTableWidget):
def __init__(self):
# ...
self.setProperty('hideSortIndicatorColumn', 0)
请注意,对于具有子级的复杂小部件而言,在小部件上设置样式并不总是足够的。 在您的情况下,它可以工作,因为您将当前样式添加到代理构造函数,但这意味着样式的所有权将由代理完全获取,并且任何其他 QWidget 将使用该代理瞬间(这几乎与将代理设置为整个应用程序相同)。 另一种方法是创建不带任何参数的代理(在这种情况下,将使用默认原生样式的 新实例),但这也意味着 no小部件将继承样式,因为 QStyles 不会传播给它们的子级。
【讨论】:
它与 PyQt5 完美配合,但我有AttributeError: 'PySide6.QtWidgets.QStyleOption' object has no attribute 'section'
和 AttributeError: 'PySide6.QtWidgets.QStyleOption' object has no attribute 'orientation'
与 PySide。
Mh。我知道在当前过渡到 Qt6 期间正在进行一些更改(如果你真的不需要它,这是一个很好的理由现在避免它)。您完全使用了我的代码吗?为了安全起见,您可以确保 opt
是 QStyleOptionHeader
类型。 opt.rect
和 opt.direction
是 not 我正在使用的:opt.rect
是绘画发生的矩形,direction
是 书写方向(用于从右到左的语言),并且 PySide 的属性也相同(包括 PySide6):doc.qt.io/qtforpython/PySide6/QtWidgets/QStyleOptionHeader.html
它仅适用于 PyQt5,opt 始终为 QStyleOption
与 PySide2 和 PySide6。
@0lan 我现在无法使用 PySide,如果您尝试使用当前选项创建一个新选项怎么办? newopt = QtWidgets.QStyleOptionHeader(opt)
然后将 newopt
用于函数的其余部分。以上是关于使用 PyQt/PySide 禁用 QTableWidget 中特定列中的排序箭头的主要内容,如果未能解决你的问题,请参考以下文章
将 vtkOrientationMarkerWidget 与 QVTKRenderWindowInteractor 一起使用 [PyQt4/PySide]
PyQt/Pyside - 也使用 valueChanged 返回先前的值
如何使用 PyQt/PySide 获取与特定文件类型关联的图标?