#include "freezetablewidget.h" #include #include #include #include FreezeTableWidget::FreezeTableWidget(QWidget *parent) : QTableView(parent) , m_frozenColumns(2) // Всегда замораживаем первые 2 столбца , frozenTableView(nullptr) { frozenTableView = new QTableView(this); //connect the headers and scrollbars of both tableviews together connect(horizontalHeader(),&QHeaderView::sectionResized, this, &FreezeTableWidget::updateSectionWidth); connect(verticalHeader(),&QHeaderView::sectionResized, this, &FreezeTableWidget::updateSectionHeight); connect(frozenTableView->verticalScrollBar(), &QAbstractSlider::valueChanged, verticalScrollBar(), &QAbstractSlider::setValue); connect(verticalScrollBar(), &QAbstractSlider::valueChanged, frozenTableView->verticalScrollBar(), &QAbstractSlider::setValue); } FreezeTableWidget::~FreezeTableWidget() { delete frozenTableView; } void FreezeTableWidget::setFrozenColumns(int count) { // ЗАКОММЕНТИРОВАНО: Динамическое изменение количества замороженных столбцов // Всегда используем первые 2 столбца // if (m_frozenColumns != count) { // m_frozenColumns = count; // // if (model()) { // // Обновляем видимость столбцов в замороженной таблице // for (int col = 0; col < model()->columnCount(); ++col) { // frozenTableView->setColumnHidden(col, col >= m_frozenColumns); // } // // updateFrozenTableGeometry(); // } // } } void FreezeTableWidget::init() { frozenTableView->setModel(model()); frozenTableView->setFocusPolicy(Qt::NoFocus); frozenTableView->verticalHeader()->hide(); frozenTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); viewport()->stackUnder(frozenTableView); // Убираем стиль для демонстрации - используем обычный вид frozenTableView->setSelectionModel(selectionModel()); // Скрываем все столбцы кроме первых 2 (ID и обозначение) for (int col = 0; col < model()->columnCount(); ++col) { frozenTableView->setColumnHidden(col, col >= 2); } // Устанавливаем ширину замороженных столбцов for (int col = 0; col < 2 && col < model()->columnCount(); ++col) { frozenTableView->setColumnWidth(col, columnWidth(col)); } frozenTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); frozenTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); frozenTableView->show(); updateFrozenTableGeometry(); setHorizontalScrollMode(ScrollPerPixel); setVerticalScrollMode(ScrollPerPixel); frozenTableView->setVerticalScrollMode(ScrollPerPixel); // Отключаем возможность изменения замороженных столбцов через клики frozenTableView->horizontalHeader()->setSectionsClickable(false); frozenTableView->horizontalHeader()->setSortIndicatorShown(false); } void FreezeTableWidget::setModel(QAbstractItemModel *model) { QTableView::setModel(model); if (model) { init(); } } void FreezeTableWidget::updateSectionWidth(int logicalIndex, int /* oldSize */, int newSize) { // Обновляем ширину только первых 2 столбцов if (logicalIndex < 2) { frozenTableView->setColumnWidth(logicalIndex, newSize); updateFrozenTableGeometry(); } } void FreezeTableWidget::updateSectionHeight(int logicalIndex, int /* oldSize */, int newSize) { frozenTableView->setRowHeight(logicalIndex, newSize); } void FreezeTableWidget::resizeEvent(QResizeEvent * event) { QTableView::resizeEvent(event); updateFrozenTableGeometry(); } QModelIndex FreezeTableWidget::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) { QModelIndex current = QTableView::moveCursor(cursorAction, modifiers); if (cursorAction == MoveLeft && current.column() > 0 && visualRect(current).topLeft().x() < frozenTableView->columnWidth(0) ){ const int newValue = horizontalScrollBar()->value() + visualRect(current).topLeft().x() - frozenTableView->columnWidth(0); horizontalScrollBar()->setValue(newValue); } return current; } void FreezeTableWidget::scrollTo (const QModelIndex & index, ScrollHint hint){ if (index.column() >= 2) QTableView::scrollTo(index, hint); } void FreezeTableWidget::updateFrozenTableGeometry() { if (!model()) return; // Вычисляем общую ширину первых 2 столбцов int frozenWidth = 0; for (int col = 0; col < 2 && col < model()->columnCount(); ++col) { frozenWidth += columnWidth(col); } frozenTableView->setGeometry(verticalHeader()->width() + frameWidth(), frameWidth(), frozenWidth, viewport()->height()+horizontalHeader()->height()); } void FreezeTableWidget::mousePressEvent(QMouseEvent *event) { // Проверяем, не кликнули ли мы в области замороженных столбцов if (event->x() < frozenTableView->width()) { // Если клик в замороженной области, игнорируем его // Это предотвращает изменение замороженных столбцов return; } // Иначе обрабатываем клик как обычно QTableView::mousePressEvent(event); } void FreezeTableWidget::mouseDoubleClickEvent(QMouseEvent *event) { // Проверяем, не кликнули ли мы в области замороженных столбцов if (event->x() < frozenTableView->width()) { // Если двойной клик в замороженной области, игнорируем его return; } // Иначе обрабатываем двойной клик как обычно QTableView::mouseDoubleClickEvent(event); } void FreezeTableWidget::contextMenuEvent(QContextMenuEvent *event) { // Проверяем, не кликнули ли мы в области замороженных столбцов if (event->x() < frozenTableView->width()) { // Если контекстное меню в замороженной области, игнорируем его return; } // Иначе обрабатываем контекстное меню как обычно QTableView::contextMenuEvent(event); }