Перейти к содержимому

Qt как выделить заголовок qtablewidget

  • автор:

Как сделать заголовки QTableWidget редактируемыми?

Я хочу чтобы пользователь мог изменять заголовки прямо в программе. Думал сделать через QTableWidgetItem , но это не сработало:

title = QTableWidgetItem() title.setFlags(Qt.ItemIsEditable) self.start.table.setHorizontalHeaderItem(1,title) 

Отслеживать
73.5k 110 110 золотых знаков 38 38 серебряных знаков 55 55 бронзовых знаков
задан 5 окт 2019 в 18:57
Николай Михайлов Николай Михайлов
13 2 2 бронзовых знака

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

QTableWidget::setHorizontalHeaderItem(int column, QTableWidgetItem *item)

Устанавливает горизонтальный элемент заголовка для столбца столбца в item.

QTableWidgetItem::setText(const QString &text)

Устанавливает item’s text в указанный text.

from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.tableWidget = QTableWidget(2, 3) self.tableWidget.setHorizontalHeaderLabels(["A", "B", "C"]) self.lineEdit_0 = QLineEdit() self.lineEdit_1 = QLineEdit() self.lineEdit_2 = QLineEdit() lay = QGridLayout(self) lay.addWidget(self.tableWidget, 0, 0, 1, 3) lay.addWidget(self.lineEdit_0, 1, 0) lay.addWidget(self.lineEdit_1, 1, 1) lay.addWidget(self.lineEdit_2, 1, 2) lay.addWidget(QPushButton("New Header 0", clicked=self.onClick), 2, 0) lay.addWidget(QPushButton("New Header 1", clicked=self.onClick), 2, 1) lay.addWidget(QPushButton("New Header 2", clicked=self.onClick), 2, 2) def onClick(self): sender = self.sender() if sender.text() == "New Header 0": title = QTableWidgetItem() #  

введите сюда описание изображения

Update

Я бы хотел чтобы заголовки редактировались как и ячейки:двойной щелчёк мышкой и пишешь прямо в заголовке.

Класс QHeaderView предоставляет строку заголовка или столбец заголовка для представлений элементов.

from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * class HeaderView(QtWidgets.QHeaderView): def __init__(self, parent): super(HeaderView, self).__init__(QtCore.Qt.Horizontal, parent) self.m_labels = [] self.sectionResized.connect(self.adjustPositions) self.sectionCountChanged.connect(self.onSectionCountChanged) self.parent().horizontalScrollBar().valueChanged.connect(self.adjustPositions) @QtCore.pyqtSlot() def onSectionCountChanged(self): while self.m_labels: label = self.m_labels.pop() label.deleteLater() for i in range(self.count()): label = QtWidgets.QLineEdit(self) label.setStyleSheet("QLineEdit < color: red; font-size: 12px; >") self.m_labels.append(label) self.update_data() self.adjustPositions() def setModel(self, model): super(HeaderView, self).setModel(model) if self.model() is not None: self.model().headerDataChanged.connect(self.update_data) def update_data(self): option = QtWidgets.QStyleOptionHeader() self.initStyleOption(option) for i, label in enumerate(self.m_labels): text = self.model().headerData( i, self.orientation(), QtCore.Qt.DisplayRole ) label.setText(str(text)) pal = label.palette() bc = self.model().headerData( i, self.orientation(), QtCore.Qt.BackgroundRole ) if bc is None: bc = option.palette.brush(QtGui.QPalette.Window) pal.setBrush(QtGui.QPalette.Window, bc) fc = self.model().headerData( i, self.orientation(), QtCore.Qt.ForegroundRole ) if fc is None: fc = option.palette.brush(QtGui.QPalette.ButtonText) pal.setBrush(QtGui.QPalette.ButtonText, fc) label.setPalette(pal) textAlignment = self.model().headerData( i, self.orientation(), QtCore.Qt.TextAlignmentRole ) if textAlignment is None: textAlignment = self.defaultAlignment() label.setAlignment(textAlignment) def updateGeometries(self): super(HeaderView, self).updateGeometries() self.adjustPositions() @QtCore.pyqtSlot() def adjustPositions(self): for index, label in enumerate(self.m_labels): geom = QtCore.QRect( self.sectionViewportPosition(index), 0, self.sectionSize(index), self.height(), ) geom.adjust(2, 0, -2, 0) label.setGeometry(geom) class Dialog(QDialog): def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.tableWidget = QTableWidget(2, 3) header = HeaderView(self.tableWidget) self.tableWidget.setHorizontalHeader(header) header_labels = [] for i in range(self.tableWidget.columnCount()): header_label = "Column-<>".format(i) header_labels.append(header_label) self.tableWidget.setHorizontalHeaderLabels(header_labels) lay = QGridLayout(self) lay.addWidget(self.tableWidget) if __name__ == "__main__": import sys app = QApplication(sys.argv) w = Dialog() w.resize(340, 150) w.exec_() 

Qt C++ qtableWidget как отловить нажатие на заголовок столбца?

Нужно вызвать событие void при клике на заголовок столбца с передачей индекса этого столбца, как сделать?

  • Вопрос задан более трёх лет назад
  • 288 просмотров

Комментировать

Решения вопроса 0

Ответы на вопрос 1

IGHOR

Ighor July @IGHOR Куратор тега Qt

Qt/C++ DEV/CTO

Возможно тут ответили на ваш вопрос https://stackoverflow.com/questions/11596267/qtabl.
PS: QTableWidget очень медленный если у вас больше 20 строк, следует использовать модель и QTableView

Ответ написан более трёх лет назад

Комментировать

Нравится 1 Комментировать

Qt C++ qtableWidget как запретить выделение столбца и заменить сортировкой при клике по заголовку?

Есть таблица qtableWidget, при клике на заголовок столбца происходит его выделение, как запретить выделение и вызывать событие void с передачей индекса нажатого столбца для сортировки?

ПС
Как сделать запрет выделения понял, а как передать индекс столбца?

Будущим поколениям в поиске.

// Запрет выделения столбца и выделение всей строки ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); // Запрет массового выделения ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  • Вопрос задан более трёх лет назад
  • 1280 просмотров

1 комментарий

Простой 1 комментарий

QTableView, интерактивное изменение заголовков

Здравствуйте.
Нужно добавить возможность изменения заголовков таблицы пользователем.
Кликнув 2 раза на ячейке можно изменить её. С заголовком это не проходит.
1) Как отловить клик мыши по заголовку?
При изменении ячейки мне нужно проверить, что введено число. И в случае ошибки вывести сообщение.
2) Какую функцию переопределить? Куда копать?

ecnpyt
23.01.10 13:38:43 MSK

model->setHeader() — так можно сменить заголовок.

Представление умеет сортировку по клику, значит мышь ловить оно умеет)

wyldrodney ☆
( 23.01.10 14:07:09 MSK )
Ответ на: комментарий от wyldrodney 23.01.10 14:07:09 MSK

Про model->setHeader() я знаю.

Ещё я знаю, что прийдется создать класс, который унаследует QTableView.
Продолжаю копать док-ю.

ecnpyt
( 23.01.10 14:24:48 MSK ) автор топика
Ответ на: комментарий от ecnpyt 23.01.10 14:24:48 MSK

может поможет сделать своего наследника QTableWidgetItem, назначить ему уже события на клики, и потом сделать setHorizontalHeaderItem(i, item) для каждого столбца при создании таблички?

RedPossum ★★★★★
( 23.01.10 14:53:35 MSK )
Ответ на: комментарий от RedPossum 23.01.10 14:53:35 MSK

но это для QTableWidget

RedPossum ★★★★★
( 23.01.10 14:54:30 MSK )

это надо читать маны в сторону делегатов (delegates)

azure ★★
( 23.01.10 16:01:13 MSK )

Секции QHeaderView не имеют индексов в модели (QModelIndex), поэтому редактировать их обычным способом не получится. Можно обрабатывать сигнал QHeaderView::sectionDoubleClicked ( int logicalIndex ), создавая редактор над указанной секцией.

Редактором тогда будет какой-нибудь QLineEdit, через installEventFilter получающий фильтр, который должен будет ловить нажатия Enter, Esc и т.д., подтверждая изменения через QSqlQueryModel::setHeaderData() например, и/или уничтожая редактор.

При изменении ячейки мне нужно проверить, что введено число

Если для указанного QLineEdit при создании вызвать setValidator( new QIntValidator( this ) ), то ввести туда можно будет только целое число.

summatus ★
( 23.01.10 18:39:26 MSK )
Ответ на: комментарий от azure 23.01.10 16:01:13 MSK

Спасибо. Я создал делегата, у которого в качестве редактора используется QDoubleSpinBox. Это решило проблему фильтрации ввода автоматически.

ecnpyt
( 24.01.10 12:49:21 MSK ) автор топика
Ответ на: комментарий от summatus 23.01.10 18:39:26 MSK

Да, спасибо за подсказки.
Из QTableView я смог получить QHeaderView. И соединить сигнал sectionDoubleClicked ( int logicalIndex ) со своим слотом.

Но как создать над заголовком редактор пока не понял.

ecnpyt
( 24.01.10 12:52:06 MSK ) автор топика
Ответ на: комментарий от ecnpyt 24.01.10 12:52:06 MSK

Пока что я сделал проще. При нажатии на заголовок появляется диалог со строкой ввода. А потом я просто устанавливаю новое имя.
Вот кусочек кода из слота:
bool ok;
QString text = QInputDialog::getText(this, tr(«QInputDialog::getText()»), tr(«Заголовок:»), QLineEdit::Normal,
tr("")), &ok);
if (ok && !text.isEmpty()) {
QStandardItem *p_item = new QStandardItem(text);
tablemodel->setVerticalHeaderItem(section, p_item);
}

Но вопрос с созданием редактора внутри заголовка открыт.
Я попробовал применить к QHeaderView делагат, который создал для обычных ячеек. QHeaderView является потомком QAbstractView, у которого есть метод setItemDelegate. Но по нажатию на заголовок редактор не появляется, заголовок просто выделяется. Наверно, надо изменить какие-то свойства заголовка, но я не нашел ничего подходящего.

ecnpyt
( 24.01.10 13:14:19 MSK ) автор топика
Ответ на: комментарий от ecnpyt 24.01.10 12:52:06 MSK

>Но как создать над заголовком редактор пока не понял.

Потомок будет нарисован в родителе, если это указать, например, при его создании. Т.к. QHeaderView - часть QTableView, то если указать таблицу в качестве parent для любого виджета, он будет в ней нарисован.

Для позиционирования редактора в заголовке, видимо, придётся его помещать в какой-нибудь layout, а сам layout создавать в таблице. Методом QXXXLayout::addSpacing, задавать смещение редактора. Нужное смещение и ширину можно узнать при помощи QHeaderView::sectionSize().

Вообще правильный путь в твоём случае - наследовать QHeaderView -> EditableHeaderView, и переопределять методы обработки событий мыши и отрисовки. То что я предлагаю, в сравнении с этим - костыль.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *