#include "stickytableview_simple.h" #include #include #include #include #include StickyTableViewSimple::StickyTableViewSimple(QWidget *parent) : QTableView(parent) , m_stickyColumns(1) , m_stickyColumnWidth(0) { // Настройка горизонтального скроллбара setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); } void StickyTableViewSimple::setStickyColumns(int count) { if (m_stickyColumns != count) { m_stickyColumns = count; updateStickyColumnGeometry(); viewport()->update(); } } void StickyTableViewSimple::paintEvent(QPaintEvent *event) { // Сначала рисуем обычную таблицу QTableView::paintEvent(event); // Затем рисуем липкие столбцы поверх if (m_stickyColumns > 0 && model()) { QPainter painter(viewport()); paintStickyColumns(&painter); } } void StickyTableViewSimple::scrollContentsBy(int dx, int dy) { QTableView::scrollContentsBy(dx, dy); // Обновляем геометрию липких столбцов после скролла updateStickyColumnGeometry(); } void StickyTableViewSimple::resizeEvent(QResizeEvent *event) { QTableView::resizeEvent(event); updateStickyColumnGeometry(); } void StickyTableViewSimple::updateStickyColumnGeometry() { if (!model() || m_stickyColumns <= 0) return; // Вычисляем ширину липких столбцов m_stickyColumnWidth = 0; for (int i = 0; i < m_stickyColumns && i < model()->columnCount(); ++i) { m_stickyColumnWidth += columnWidth(i); } // Устанавливаем отступ для основного контента setViewportMargins(m_stickyColumnWidth, 0, 0, 0); } void StickyTableViewSimple::paintStickyColumns(QPainter *painter) { if (!model() || m_stickyColumns <= 0) return; // Сохраняем состояние painter painter->save(); // Настраиваем clipping для липких столбцов QRect stickyRect = QRect(0, 0, m_stickyColumnWidth, viewport()->height()); painter->setClipRect(stickyRect); // Получаем видимые строки (упрощенный подход) int visibleRows = model()->rowCount(); int startRow = 0; int endRow = visibleRows - 1; // Рисуем липкие столбцы for (int row = startRow; row <= endRow && row < model()->rowCount(); ++row) { int y = rowViewportPosition(row); int currentRowHeight = rowHeight(row); for (int col = 0; col < m_stickyColumns && col < model()->columnCount(); ++col) { int x = 0; for (int i = 0; i < col; ++i) { x += columnWidth(i); } QRect cellRect(x, y, columnWidth(col), currentRowHeight); // Рисуем фон ячейки QModelIndex index = model()->index(row, col); QStyleOptionViewItem option; option.initFrom(this); option.rect = cellRect; option.state = QStyle::State_Enabled; if (selectionModel() && selectionModel()->isSelected(index)) { option.state |= QStyle::State_Selected; } if (index == currentIndex()) { option.state |= QStyle::State_HasFocus; } style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); // Рисуем текст ячейки QVariant data = model()->data(index, Qt::DisplayRole); if (data.isValid()) { painter->drawText(cellRect.adjusted(4, 0, -4, 0), Qt::AlignVCenter | Qt::AlignLeft, data.toString()); } } } // Рисуем границы липких столбцов painter->setPen(QPen(Qt::black, 1)); painter->drawLine(m_stickyColumnWidth - 1, 0, m_stickyColumnWidth - 1, viewport()->height()); // Восстанавливаем состояние painter painter->restore(); }