Qt实现多行表头

  • 设计思路
    利用两个表格,一个表格作为表头,一个作为表格内容,表头表格高度设置为对应行数高度之和,两表采用竖向布局,竖向滚动条放置于两表右侧

  • 滚动条
    内容表格横向滚动条保持不变,竖向滚动条禁用,自定义滚动条并绑定内容表格,滚动条的显示与隐藏通过其范围变化动态设置

    connect(table_content->horizontalScrollBar(), &QScrollBar::valueChanged, table_header->horizontalScrollBar(), &QScrollBar::setSliderPosition);
    connect(table_header->horizontalScrollBar(), &QScrollBar::valueChanged, table_content->horizontalScrollBar(), &QScrollBar::setSliderPosition);
    connect(verticalScrollBar, &QScrollBar::rangeChanged, this, &Widget::verticalScrollBarHideOrShow);
    
  • 滚动条设置代码

    void Widget::verticalScrollBarHideOrShow(int min, int max)
    {
        if(min == max)
        {
            verticalScrollBar->setHidden(true);
        }
        else
        {
            verticalScrollBar->setHidden(false);
        }
    }
    
  • 完整代码

    table_header = new QTableWidget(this);
    table_content = new QTableWidget(this);
    table_header->setObjectName("table_header");
    table_content->setObjectName("table_content");
    
    table_header->horizontalHeader()->setVisible(false);
    table_header->verticalHeader()->setVisible(false);
    table_header->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    table_header->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    table_header->setFrameShape(QFrame::NoFrame);
    table_header->setFocusPolicy(Qt::NoFocus);
    table_header->setEditTriggers(QAbstractItemView::NoEditTriggers);
    table_header->setSelectionMode(QAbstractItemView::NoSelection);
    
    table_header->setRowCount(2);
    table_header->setColumnCount(5);
    table_header->setFixedHeight(table_header->rowHeight(0) + table_header->rowHeight(1));
    
    table_header->setSpan(0, 0, 2, 1);
    table_header->setItem(0, 0, new QTableWidgetItem("header1"));
    table_header->item(0, 0)->setTextAlignment(Qt::AlignCenter);
    
    table_header->setSpan(0, 1, 1, 2);
    table_header->setItem(0, 1, new QTableWidgetItem("header2"));
    table_header->item(0, 1)->setTextAlignment(Qt::AlignCenter);
    table_header->setItem(1, 1, new QTableWidgetItem("header21"));
    table_header->item(1, 1)->setTextAlignment(Qt::AlignCenter);
    table_header->setItem(1, 2, new QTableWidgetItem("header22"));
    table_header->item(1, 2)->setTextAlignment(Qt::AlignCenter);
    
    table_header->setSpan(0, 3, 1, 2);
    table_header->setItem(0, 3, new QTableWidgetItem("header3"));
    table_header->item(0, 3)->setTextAlignment(Qt::AlignCenter);
    table_header->setItem(1, 3, new QTableWidgetItem("header31"));
    table_header->item(1, 3)->setTextAlignment(Qt::AlignCenter);
    table_header->setItem(1, 4, new QTableWidgetItem("header32"));
    table_header->item(1, 4)->setTextAlignment(Qt::AlignCenter);
    
    table_content->horizontalHeader()->setVisible(false);
    table_content->verticalHeader()->setVisible(false);
    table_content->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    table_content->setFrameShape(QFrame::NoFrame);
    table_content->setFocusPolicy(Qt::NoFocus);
    table_content->setSelectionBehavior(QAbstractItemView::SelectRows);
    table_content->setSelectionMode(QAbstractItemView::SingleSelection);
    table_content->setAlternatingRowColors(true);
    table_content->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    table_content->setColumnCount(5);
    table_content->setRowCount(10);
    for(int i=0; i<15; i++)
    {
        table_content->setItem(i/5, i%5, new QTableWidgetItem("item"+QString::number(i/5)+QString::number(i%5)));
    }
    
    verticalScrollBar = new QScrollBar(Qt::Vertical, this);
    table_content->setVerticalScrollBar(verticalScrollBar);
    
    connect(table_content->horizontalScrollBar(), &QScrollBar::valueChanged, table_header->horizontalScrollBar(), &QScrollBar::setSliderPosition);
    connect(table_header->horizontalScrollBar(), &QScrollBar::valueChanged, table_content->horizontalScrollBar(), &QScrollBar::setSliderPosition);
    connect(verticalScrollBar, &QScrollBar::rangeChanged, this, &Widget::verticalScrollBarHideOrShow);
    
    QVBoxLayout *vb_no_vertical_scrollbar = new QVBoxLayout();
    vb_no_vertical_scrollbar->addWidget(table_header);
    vb_no_vertical_scrollbar->addWidget(table_content);
    vb_no_vertical_scrollbar->setSpacing(0);
    
    QHBoxLayout *hb_tables = new QHBoxLayout(this);
    hb_tables->addLayout(vb_no_vertical_scrollbar);
    hb_tables->addWidget(verticalScrollBar);
    
    this->setStyleSheet("QTableWidget#table_header::item{background-color:lightgray;} QTableWidget#table_header{gridline-color:gray;} QTableWidget#table_content::item::selected{background-color:lightgreen;color:white;}");
    
  • 运行结果
    Qt实现多行表头_第1张图片

你可能感兴趣的:(qt)