Стилизация заголовка таблицы
Была таблица. Получала данные из БД, отрисовывала данные и т.д. И стала она длинной в километр. И захотелось мне повернуть текст в заголовках на 90 градусов. Сам этого тоже не смог, ответили в другой теме.
Применил следующий код:
from PyQt6 import QtWidgets, QtGui, QtCore
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import *
from PyQt6.QtWidgets import QTableWidgetItem
class MyHeaderView(QHeaderView):
def __init__(self, parent=None):
super().__init__(QtCore.Qt.Orientation.Horizontal, parent)
self._font = QtGui.QFont("Times", 10, QFont.Weight.Bold)
self._metrics = QtGui.QFontMetrics(self._font)
self._descent = self._metrics.descent()
# self.setStyleSheet("QHeaderView {background-color: #ffffff;}")
def paintSection(self, painter, rect, index):
data = self._get_data(index)
if index == 2 or index == 3 or index >= 7:
painter.drawRect(rect)
painter.rotate(-90)
painter.setFont(self._font)
painter.drawText(
QtCore.QPointF(- rect.height(), rect.left() + (rect.width() + self._descent) / 2), data)
else:
super().paintSection(painter, rect, index)
def sizeHint(self):
return QtCore.QSize(0, self._get_text_width() + 2)
#
def _get_text_width(self):
return max([self._metrics.boundingRect(self._get_data(i)).width() for i in range(0, self.model().columnCount())])
def _get_data(self, index):
return self.model().headerData(index, self.orientation())
class WindowBakeryTablesEdit(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.centralwidget = QtWidgets.QWidget(WindowBakeryTables)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setObjectName("tableWidget")
self.verticalLayout.addWidget(self.tableWidget)
self.tableWidget.setRowCount(7) # Для примера
self.tableWidget.setColumnCount(11) # Для примера
self.verticalLayout.addWidget(self.tableWidget)
self.columnLables = ['', '', 'Кф. товара', 'Выкладка', 'Код блюда', 'Блюдо', 'Категория блюда', 'Беговая', 'Вольск', 'Горького', 'Гранд'] # Далее еще очень много заголовков.
self.headerView = MyHeaderView()
self.tableWidget.setHorizontalHeader(self.headerView)
self.tableWidget.setHorizontalHeaderLabels(self.columnLables)
self.font = QtGui.QFont("Times", 10, QFont.Weight.Bold)
self.tableWidget.horizontalHeader().setFont(self.font)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
WindowBakeryTables = QtWidgets.QMainWindow()
WindowBakeryTables.show()
sys.exit(app.exec())
И вроде бы все хорошо. Нужные мне заголовки развернулись.
Но появилась другая проблема. Изменилось оформление этих заголовков, а очень хочется что бы все было в едином стиле. Как на первом скрине. Если есть знающие люди, подскажите как можно исправить? Сразу прошу прощения, если код может оказаться неполный. Сам UI делал в программе и подключал отдельно. Но постарался перенести все необходимое для минимального примера.
Если раскоментировать эту часть:
# self.setStyleSheet("QHeaderView {background-color: #ffffff;}")
То получается вот такой результат:
Лучше, но я так и не смог поправить границы ячеек. Мучаю этот вопрос уже 3 день, очень хотелось найти решение самому, но силы мои слабеют))
Ответы (2 шт):
Для стилизации можно использовать любой виджет, например:
def paintSection(self, painter, rect, index):
# Если надо рамочку, то рисовать тут же
data = self._get_data(index)
# Виджет-мул
edit = QLineEdit()
## или, например, с QLabel
## edit = QLabel()
## edit.setFrameShadow(QFrame.Shadow.Raised)
## edit.setFrameShape(QFrame.Shape.WinPanel)
edit.setText(data)
# Где-то тут можно изменить шрифт текста, css и тому подобный стаф
# edit.setStyleSheet("background-color: orange") # ммм, апельсиновый
# Размер виджета-мула соответствует размеру ячейки с
# переставленными высотой и шириной
edit.setGeometry(rect.left(), rect.top(), rect.height(), rect.width())
# pixmap нужен, чтобы на него отобразить виджет,
# а затем нарисовать его на холсте QPainter
pixmap = QPixmap(edit.size())
# Рендерим (отображаем) виджет на pixmap
edit.render(pixmap )
# Не самый шустрый способ поворота, но в 98,5% случаев норм
t = QTransform() # трансформатор
t.translate(rect.center().x(), rect.center().y()) # смещаемся в центр
t.rotate(-90) # Задаем вращение
pixmap = pixmap.transformed(t) # Трансформируем
# Рисуем повернутую картинку на холсте ячейки
painter.drawPixmap(rect.topLeft(), pixmap)
Как вариант:
'''
from PyQt6 import QtWidgets, QtGui, QtCore
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import *
from PyQt6.QtWidgets import QTableWidgetItem
'''
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.Qt import *
class MyHeaderView(QHeaderView):
def __init__(self, parent=None):
super().__init__(QtCore.Qt.Orientation.Horizontal, parent)
self._font = QtGui.QFont("Times", 10, QFont.Weight.Bold)
self._metrics = QtGui.QFontMetrics(self._font)
self._descent = self._metrics.descent()
def paintSection(self, painter, rect, index):
data = self._get_data(index)
painter.setPen(QPen(Qt.blue, 2, Qt.SolidLine))
painter.drawRect(rect.x(), rect.y(), rect.width()+.1, rect.height()+1.2)
if index == 2 or index == 3 or index >= 7:
painter.rotate(-90)
painter.setFont(self._font)
painter.drawText(
QtCore.QPointF(
- rect.height()+15,
rect.left() + (rect.width() + self._descent) / 2
),
data
)
else:
super().paintSection(painter, rect, index)
def sizeHint(self):
return QtCore.QSize(0, self._get_text_width() + 2)
def _get_text_width(self):
return max([self._metrics.boundingRect(self._get_data(i)).width() \
for i in range(0, self.model().columnCount())])
def _get_data(self, index):
return self.model().headerData(index, self.orientation())
class WindowBakeryTablesEdit(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.centralwidget = QtWidgets.QWidget()
self.centralwidget.setObjectName("centralwidget")
self.setCentralWidget(self.centralwidget)
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setObjectName("tableWidget")
self.verticalLayout.addWidget(self.tableWidget)
self.tableWidget.setRowCount(7)
self.tableWidget.setColumnCount(11)
self.columnLables = ['', '', 'Кф. товара', 'Выкладка',
'Код блюда', 'Блюдо', 'Категория блюда', 'Беговая',
'Вольск', 'Горького', 'Гранд']
self.headerView = MyHeaderView()
self.tableWidget.setHorizontalHeader(self.headerView)
self.tableWidget.setHorizontalHeaderLabels(self.columnLables)
self.font = QtGui.QFont("Times", 10, QFont.Weight.Bold)
self.tableWidget.horizontalHeader().setFont(self.font)
self.tableWidget.horizontalHeader().setStyleSheet('''
QHeaderView {
border: none;
border-bottom: 2px solid blue;
border-top: 2px solid blue;
color: #00f;
}
QHeaderView::section:horizontal {
border: none;
border-right: 2px solid blue;
border-left: 1px solid blue;
min-height: 48px;
}
''')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle(QStyleFactory.create("Fusion"))
w = WindowBakeryTablesEdit()
w.resize(1160, 400)
w.show()
sys.exit(app.exec())


