Qt文档阅读笔记-两视图共享模型实现冻结列效果(frozencolumn解析与实例)

目录

官方解析

博主例子


 

官方解析

官方有个很好的例子:

Frozen Column Example

但感觉有点冗余!在后面我将修改官方的例子,以及说明下这个效果的原理:

 

Qt模型视图框架

使用两个视图在同一个模型上,使用叠加技术,到达冻结某列的效果,

原理:两视图共享模型!


先把一个视图放到另外一个视图上面,只保留某一列显示,其他列隐藏,并且使用stackUnder()把其放在最上面,然后第二个模型在他下面。

隐藏视图的竖直方向上的头部

 

说白了,就是一个view放到另外一个view的上面,上面的view不动,下面的view动,就可以实现这种效果!

 

博主例子

程序运行截图如下:

Qt文档阅读笔记-两视图共享模型实现冻结列效果(frozencolumn解析与实例)

 

源码如下:

mytableview.h

#ifndef MYTABLEVIEW_H
#define MYTABLEVIEW_H

#include <QTableView>

QT_BEGIN_NAMESPACE
class QStandardItemModel;
QT_END_NAMESPACE

class MyTableView : public QTableView
{
    Q_OBJECT
public:
    MyTableView(QWidget *parent = 0);

protected:
    void updateTopTableViewGeometry();
    void resizeEvent(QResizeEvent *event)Q_DECL_OVERRIDE;

private:
    void init();
    QTableView *m_topTableView;
    QStandardItemModel *m_model;

};

#endif // MYTABLEVIEW_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

mytableview.cpp

#include "mytableview.h"
#include <QStandardItemModel>
#include <QHeaderView>
#include <QScrollBar>
#include <QDebug>

MyTableView::MyTableView(QWidget *parent) : QTableView(parent)
{
    m_model=new QStandardItemModel;

    QStringList headList;
    headList<<"bottomView col 1"<<"bottomView col 2"<<"bottomView col 3"
        <<"bottomView col 4"<<"bottomView col 5"<<"bottomView col 6"
        <<"bottomView col 7"<<"bottomView col 8"<<"bottomView col 9";

    m_model->setHorizontalHeaderLabels(headList);

    for(int i=0;i<100;i++){
        for(int j=0;j<9;j++){
            QStandardItem *newItem=new QStandardItem("row: "+QString::number(i+1)+"  col: "+QString::number(j+1));
            m_model->setItem(i,j,newItem);
        }
    }

    setModel(m_model);
    horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

    init();
    connect(m_topTableView->verticalScrollBar(), &QAbstractSlider::valueChanged,
            verticalScrollBar(), &QAbstractSlider::setValue);
    connect(verticalScrollBar(), &QAbstractSlider::valueChanged,
            m_topTableView->verticalScrollBar(), &QAbstractSlider::setValue);
}

void MyTableView::updateTopTableViewGeometry()
{
    m_topTableView->setGeometry(verticalHeader()->width()+frameWidth()
                                ,frameWidth()
                                ,columnWidth(0)
                                ,viewport()->height()+horizontalHeader()->height());
}

void MyTableView::resizeEvent(QResizeEvent *event)
{
    QTableView::resizeEvent(event);
    updateTopTableViewGeometry();
}

void MyTableView::init()
{
    m_topTableView=new QTableView(this);
    m_topTableView->setFocusPolicy(Qt::NoFocus);
    m_topTableView->verticalHeader()->hide();
    m_topTableView->setModel(m_model);
    m_topTableView->setStyleSheet("QTableView { border: none;"
                                  "background-color: rgb(255,255,0);"
                                  "selection-background-color: rgb(0,255,255)}");
    m_topTableView->setSelectionModel(selectionModel());

    for(int i=1;i<m_model->columnCount();i++){
        m_topTableView->setColumnHidden(i,true);
    }

    m_topTableView->setColumnWidth(0,columnWidth(0));
    m_topTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_topTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    updateTopTableViewGeometry();

    setHorizontalScrollMode(ScrollPerPixel);
    setVerticalScrollMode(ScrollPerPixel);
    m_topTableView->setVerticalScrollMode(ScrollPerPixel);
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}