Я хотел бы удалить стрелку из заголовка первого столбца, чтобы заголовок был центрирован с помощью флажков. Все это без отключения возможности сортировки столбца.
Это мой текущий код.
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_())
Самое простое решение — переопределить drawControl() и установить для indicator
QStyleOptionHeader значение 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 будет использовать прокси с этого момента (что почти так же, как установка прокси для всего приложения).
Альтернативой является создание прокси без каких-либо аргументов (в этом случае будет использоваться новый экземпляр собственного стиля по умолчанию), но это также означает, что ни один из дочерних элементов виджета не наследует стиль, поскольку QStyles не распространяется на их дочерние элементы. .
Мх. Я знаю, что во время текущего перехода на Qt6 вносятся некоторые изменения (что является хорошей причиной избегать его прямо сейчас, если он вам действительно не нужен). Вы использовали именно мой код? На всякий случай вы можете убедиться, что opt
является типом QStyleOptionHeader
. opt.rect
и opt.direction
не то, что я использую: 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
для остальной части функции.
Он отлично работает с PyQt5, но у меня есть
AttributeError: 'PySide6.QtWidgets.QStyleOption' object has no attribute 'section'
иAttributeError: 'PySide6.QtWidgets.QStyleOption' object has no attribute 'orientation'
с PySide.