QTableView实现冻结行冻结列

本文介绍了一种在Qt中实现QTableView冻结行和列的技术,避免了使用多个QTableView导致的内存占用问题。通过添加滚动条并覆盖在QTableView的原生滚动条上,以及重写QTableView的resizeEvent来确保冻结效果。同时,通过滚动条的actionTriggered信号和事件过滤器处理键盘箭头事件,实现了对显示和隐藏的行和列的控制,允许数据编辑和调整行宽、列宽等功能。
摘要由CSDN通过智能技术生成

一、效果展示

 

二、实现思路

Qt自带的示例Frozen Column Exmaple实现冻结列的思路为用一个QTableView盖住另一个QTableView并只显示冻结的列,共用一个Model,该方法存在占用内存,若按其思路同时冻结行和列则需要创建行列各一个QTableView还有相交部分一个QTableView,而且同时滚动时不方便处理,也不能对数据进行编辑不能进行行宽列宽的调事等操作,在尝试后,放弃使用其实现方法。这里采用的冻结行和冻结列的思路为添加行列滚动条设置其parent为QTableView自带的滚动条,覆盖显示在滚动条上,并通过重写QTableView的resizeEvent来保证添加的滚动条始终覆盖QTableView自动的滚动条。冻结为设置QTableView自滚动条的value值为零,则始终会显示冻结列和冻结行,然后计算滚动时需要隐藏和显示的行和列,则只需要一个QTableView,这样可进行编辑、行宽、列宽等操作,占用内存也少。通过滚动条的actionTriggered(int action)信号对QTableView的item显示和隐藏进行控制,通过eventFilter处理QTableView的键盘箭头向上、箭头向下、箭头向左和箭头向右四个键按下事件,控制item的显示和隐藏。

三、核心代码

freezetableview.h

#ifndef FREEZETABLEVIEW_H
#define FREEZETABLEVIEW_H

#include <QTableView>
#include <QScrollBar>
#include <QMap>

class FreezeTableView : public QTableView
{
    Q_OBJECT
public:
    FreezeTableView(QWidget *parent = nullptr);
    //冻结前几行
    void freezeRow(int freezeRowNum);
    //取消冻结前几行
    void cancelFreezeRow();
    //冻结结前几列
    void freezeColumn(int freezeColumnNum);
    //取消冻结前几列
    void cancelFreeColumn();
    //设置冻结的行列的背景色
    void setFreezeBackgroundColor(QColor color);
protected:
     void resizeEvent(QResizeEvent *event) override;
     bool eventFilter(QObject* object,QEvent* event) override;
private:
     //垂直滚动条
     QScrollBar* m_vScrollBar;
     //水平滚动条
     QScrollBar* m_hScrollBar;
     //冻结的行数
     int  m_freezeRowNum;
     //冻结的列数
     int  m_freezeColumnNum;
     //保存各行的显示隐藏状态
     QMap<int,bool> m_rowVisibleMap;
     //保存各列的显示隐藏状态
     QMap<int,bool> m_columnVisibleMap;
     //冻结颜色
     QColor m_freezeBackgroundColor=Qt::gray;
     //垂直滚动条当前值对应的行
     int m_currentRow;
     //水平滚动条当前值对应的列
     int m_currentColumn;
     //保存水平滚动条的值,用于判断拖动滑块时是左移还是右移
     int m_hOldValue;
     //保存垂直滚动条的值,用于判断拖动滑块时是上移还是下移
     int m_vOldValue;
     //重置各行的显示隐藏情况
     void resetRowShowStatus();
     //重围各列的显示隐藏情况
     void resetColumnShowStatus();
     //计算冻结行的高度
     int getFreezeRowHeight();
     //计算冻结列的高度
     int getFreezeColumnWidth();
     //向下滚动
     void scrollDown(int step);
     //向上滚动
     void scrollUp(int step);
     //向左滚动
     void scrollLeft(int step);
     //向右滚动
     void scrollRight(int step);
     //箭头向下处理函数
     void moveDown();
     //箭头向上处理函数
     void moveUp();
     //箭头向左处理函数
     void moveLeft();
     //箭头向右处理函数
     void moveRight();
signals:
private slots:
   //水平滚动条ActionTriggered处理槽函数
   void hActionTriggered(int action);
   //垂直滚动条ActionTriggered处理槽函数
   void vActionTriggered(int action);

};

#endif // FREEZETABLEVIEW_H

freezetableview.cpp

#include "freezetableview.h"
#include<QHeaderView>
#include<QWheelEvent>
#include<QKeyEvent>
#include<QtMath>
#define BackupBackgroundColor Qt::UserRole+1
FreezeTableView::FreezeTableView(QWidget *parent) : QTableView(parent)
{

    m_hScrollBar=new QScrollBar(Qt::Horizontal,horizontalScrollBar());
    m_vScrollBar=new QScrollBar(Qt::Vertical,verticalScrollBar());
    connect(m_hScrollBar,&QScrollBar::actionTriggered,this,&FreezeTableView::hActionTriggered);
    connect(m_vScrollBar,&QScrollBar::actionTriggered,this,&FreezeTableView::vActionTriggered);
    m_freezeRowNum=0;
    m_freezeColumnNum=0;
    m_currentRow=0;
    m_currentColumn=0;
    m_hOldValue=0;
    m_vOldValue=
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

i2program

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值