前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >QTableView + QStandardItemModel模式显示表格冻结列(模板)

QTableView + QStandardItemModel模式显示表格冻结列(模板)

原创
作者头像
Qt历险记
发布2024-07-29 20:11:49
580
发布2024-07-29 20:11:49
举报
文章被收录于专栏:Qt6 研发工程师

点击上方"蓝字"关注我们

01、QTableView

QTableView 是 Qt 框架中一个用于显示和编辑表格数据的控件。它提供了一个灵活的界面,允许用户通过行和列来浏览和修改数据。QTableView 支持多种数据模型,如 QAbstractItemModel,并且可以与模型一起使用,以提供数据视图。此外,QTableView 还提供了排序、筛选和分组等功能,以满足不同的需求。

02、QStandardItemModel

QStandardItemModel 是 Qt 框架中一个常用的数据模型,用于存储和管理表格数据。它是一个基于 QAbstractItemModel 的实现,提供了简单易用的 API 来创建和管理表格数据。使用 QStandardItemModel,你可以轻松地将数据填充到表格中,并通过行和列索引访问和修改数据。此外,QStandardItemModel 还支持数据类型转换、数据校验和信号槽机制等功能,使得它在开发过程中非常实用。

03、QStandardItem

QStandardItem 是 Qt 框架中一个用于表示表格单元格的数据对象。它是 QStandardItemModel 的基本构建块,每个 QStandardItem 可以包含一个值和一些附加属性,如文本、图标、状态等。通过将 QStandardItem 添加到 QStandardItemModel 中,你可以构建一个完整的表格数据模型。

QStandardItem 提供了一系列方法来设置和获取其属性,例如 setText() 用于设置文本内容,setIcon() 用于设置图标,setCheckState() 用于设置复选框状态等。此外,QStandardItem 还支持父子关系管理,可以通过 setChild() 和 child() 方法来添加和访问子项。

在 QTableView 中,QStandardItem 作为数据模型中的基本元素,负责展示和编辑表格中的数据。通过操作 QStandardItem,你可以实现对表格数据的增删改查等操作。

04、QModelIndex

QModelIndex 是 Qt 框架中一个用于表示模型中某个节点的对象。在 QTableView、QListView 等控件中,QModelIndex 用来唯一标识模型中的一个元素,以便于获取和操作该元素的数据。

QModelIndex 的主要作用包括:

1. 定位元素:通过 QModelIndex 可以获取到模型中指定位置的元素,例如获取第一行的第一个单元格的 QModelIndex。

2. 访问数据:通过 QModelIndex 可以访问到模型中对应元素的数据,例如获取该元素的文本内容或图片资源。

3. 操作元素:通过 QModelIndex 可以对模型中对应元素进行操作,例如修改文本内容或更改图片资源。

在使用 QModelIndex 时,需要注意以下几点:

1. QModelIndex 是一个轻量级对象,可以在多个地方传递和使用,而不会增加内存开销。

2. QModelIndex 不包含任何数据本身,它只是一个指向模型中某个节点的指针。因此,在使用 QModelIndex 时,需要确保它指向的是一个有效的节点。

3. QModelIndex 是不可变的,即不能直接修改它的属性。如果需要对模型中的元素进行操作,需要通过模型提供的接口来实现。

05、grades.txt

 France , Norway , YDS , UK(tech.), UK(adj.) , UIAA , Ger , Australia , Finland , Brazil

1,   , 5.2,   ,   , I , I ,   ,   , Isup

2,   , 5.3,   ,   , II , II , 11,   , II

3, 3, 5.4,   ,   , III , III , 12,   , IIsup

4, 4, 5.5, 4a , VD , IV , IV , 12,   , III

5a , 5-, 5.6,   , S , V- , V , 13, 5-, IIIsup

5b , 5, 5.7, 4b , HS , V , VI , 14, 5, IV

  ,   ,   , 4c ,   , V+ ,   , 15,   ,  

5c , 5+, 5.8,   , VS , VI- , VIIa , 16, 5, IVsup

6a , 6-, 5.9, 5a , HVS , VI , VIIb , 17,   , V

6a+ , 6-/6 , 5.10a ,   , E1 , VI+ , VIIc , 18, 6-, VI

6b ,   , 5.10b , 5b ,   ,   ,   , 19,   , VI/VI+

6b+ , 6, 5.10c ,   , E2 , VII- , VIIIa , 20, 6, VIsup/VI+

6c , 6+, 5.10d , 5c ,   , VII , VIIIb , 21,   , VIsup

6c+ , 7-, 5.11a ,   , E3 , VII+ , VIIIc , 22, 6, 7a

6c+ , 7, 5.11b ,   ,   ,   ,   , 23,   , 7b

7a , 7+, 5.11c , 6a , E4 , VIII- , IXa , 24, 7-, 7c

7a , 7+/8- , 5.11d ,   ,   , VIII , IXb ,   , , 7c

7a+ , 8-, 5.12a ,   , E5 , VIII+ , IXc , 25, 7, 8a

7b , 8, 5.12b , 6b ,   ,   ,   , 26, 8-, 8b

7b+ , 8/8+ , 5.12c ,   , E6 , IX- , Xa , 27, 8, 8c

7c , 8+, 5.12d , 6c ,   , IX , Xb , 28, 8, 9a

7c+ , 9-, 5.13a ,   , E7 , IX+ , Xc , 29, 9-, 9b

8a ,   , 5.13b ,   ,   ,   ,   ,   , 9, 9c

8a+ , 9-/9 , 5.13c , 7a ,   , X- ,   , 30, 9, 10a

8b , 9, 5.13d ,   , E8 , X ,   , 31, 10-, 10b

8b+ , 9/9+ , 5.14a ,   ,   , X+ ,   , 32, 10, 10c

8c , 9+, 5.14b , 7b ,   ,   ,   , 33, 10, 11a

8c+ , 10-, 5.14c ,   , E9 , XI- ,   , 34, 11-, 11b

9a , 10, 5.14d , 7c ,   , XI ,   , 35, 11, 11c

9a+ ,   , 5.15a , ,   , XI+ ,   ,   ,   , 12a

9b , , 5.15b  , ,   , , , , , 12b

# Wikipedia contributors. Grade (climbing). Wikipedia, The Free Encyclopedia. May 15, 2009, 20:42 UTC. 

06、main.cpp

代码语言:javascript
复制
#include <QApplication>
#include <QStandardItemModel>
#include <QFile>
#include <QTextStream>

#include "freezetablewidget.h"

int main(int argc, char* argv[])
{
    Q_INIT_RESOURCE(grades);

    QApplication app( argc, argv );

    // QStandardItemModel类提供了一个用于存储自定义数据的通用模型
    QStandardItemModel *model=new QStandardItemModel();

    QFile file(":/grades.txt");
    if (file.open(QFile::ReadOnly)) {
        QTextStream stream(&file);

        QString line = stream.readLine();
        QStringList list = line.simplified().split(',');

        // 设置水平头
        model->setHorizontalHeaderLabels(list);

        int row = 0;
        QStandardItem *newItem = nullptr;
        while (!stream.atEnd()) {
            line = stream.readLine();
            if (!line.startsWith('#') && line.contains(',')) {
                list = line.simplified().split(',');
                for (int col = 0; col < list.length(); ++col){
                    newItem = new QStandardItem(list.at(col));
                    // 将给定行和列的项设置为项
                    model->setItem(row, col, newItem);
                }
                ++row;
            }
        }
    }
    file.close();

    FreezeTableWidget *tableView = new FreezeTableWidget(model);

    tableView->setWindowTitle(QObject::tr("公众号:Qt历险记"));
    tableView->resize(560, 680);
    tableView->show();
    return app.exec();
}

07、freezetablewidget.h

代码语言:javascript
复制
#ifndef FREEZETABLEWIDGET_H
#define FREEZETABLEWIDGET_H

#include <QTableView>

//! [Widget definition]
class FreezeTableWidget : public QTableView {
     Q_OBJECT

public:
      FreezeTableWidget(QAbstractItemModel * model);
      ~FreezeTableWidget();


protected:
      void resizeEvent(QResizeEvent *event) override;
      QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override;
      void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible) override;

private:
      QTableView *frozenTableView;
      void init();
      void updateFrozenTableGeometry();


private slots:
      void updateSectionWidth(int logicalIndex, int oldSize, int newSize);
      void updateSectionHeight(int logicalIndex, int oldSize, int newSize);

};
//! [Widget definition]
#endif // FREEZETABLEWIDGET_H

08、freezetablewidget.cpp

代码语言:javascript
复制
#include "freezetablewidget.h"

#include <QScrollBar>
#include <QHeaderView>

FreezeTableWidget::FreezeTableWidget(QAbstractItemModel * model)
{

     // QTableView
      setModel(model);
      frozenTableView = new QTableView(this);

      init();

      // 将两个表视图的标题和滚动条连接在一起
      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::init()
{
      frozenTableView->setModel(model());
      frozenTableView->setFocusPolicy(Qt::NoFocus);
      frozenTableView->verticalHeader()->hide();
      frozenTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

      // 将小部件放置在父小部件堆栈中的frozenTableView下。
      // 为了实现这一点,小部件本身和frozenTableView必须是兄弟姐妹。
      viewport()->stackUnder(frozenTableView);

      frozenTableView->setStyleSheet("QTableView { border: none;"
                                     "background-color: #8EDE21;"
                                     "selection-background-color: #999}"); //for demo purposes
      frozenTableView->setSelectionModel(selectionModel());
      for (int col = 1; col < model()->columnCount(); ++col)
            frozenTableView->setColumnHidden(col, true);

      frozenTableView->setColumnWidth(0, columnWidth(0) );

      frozenTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
      frozenTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
      frozenTableView->show();

      updateFrozenTableGeometry();

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


//! [sections]
void FreezeTableWidget::updateSectionWidth(int logicalIndex, int /* oldSize */, int newSize)
{
      if (logicalIndex == 0){
            frozenTableView->setColumnWidth(0, newSize);
            updateFrozenTableGeometry();
      }
}

void FreezeTableWidget::updateSectionHeight(int logicalIndex, int /* oldSize */, int newSize)
{
      frozenTableView->setRowHeight(logicalIndex, newSize);
}
//! [sections]


//! [resize]
void FreezeTableWidget::resizeEvent(QResizeEvent * event)
{
      QTableView::resizeEvent(event);
      updateFrozenTableGeometry();
 }
//! [resize]


//! [navigate]
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;
}
//! [navigate]

// 滚动到指定的模型索引(QModelIndex)
void FreezeTableWidget::scrollTo (const QModelIndex & index, ScrollHint hint){
    if (index.column() > 0)
        QTableView::scrollTo(index, hint);
}

//! [geometry]
//! updateFrozenTableGeometry()函数可以确保冻结表格总是显示在屏幕的可视区域内,并且其位置和大小会根据窗口的大小和表头的宽度自动调整。
void FreezeTableWidget::updateFrozenTableGeometry()
{
      frozenTableView->setGeometry(verticalHeader()->width() + frameWidth(),
                                   frameWidth(), columnWidth(0),
                                   viewport()->height()+horizontalHeader()->height());
}
//! [geometry]


09、.pro

代码语言:javascript
复制
QT += widgets
requires(qtConfig(tableview))

HEADERS += freezetablewidget.h
SOURCES += main.cpp freezetablewidget.cpp
RESOURCES += grades.qrc

# install
target.path = $$PWD/frozencolumn
INSTALLS += target

10、演示

总结

同志们,想学什么Qt内容,记得在下方留言。

故我在

点击下方卡片 关注我

↓↓↓

Qt历险记

一名技术分享师,分享方向:->Qt(C/C++、linux、STM32、MySql/Sqlite3、TCP/UDP),设计方面->Ai、PS、visio、AD、Protues。 【v合作:Family_S_Health】

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 点击上方"蓝字"关注我们
  • 01、QTableView
  • 02、QStandardItemModel
  • 03、QStandardItem
  • 04、QModelIndex
  • 05、grades.txt
  • 06、main.cpp
  • 07、freezetablewidget.h
  • 08、freezetablewidget.cpp
  • 09、.pro
  • 10、演示
  • 总结
  • 故我在
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档