Qt编程基础 | 第六章-窗体 | 6.3、QTableWidget

这篇具有很好参考价值的文章主要介绍了Qt编程基础 | 第六章-窗体 | 6.3、QTableWidget。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、QTableWidget

1、简介

QTableWidget是QT中的表格组件类,一般用来展示多行多列的数据,是QT中使用较多的控件之一。QTableWidgetItem用来表示表格中的一个单元格,整个表格都需要用逐个单元格构建起来。

2、QTableWidget常用方法

2.1、设置表格的行数与列数

// 设置表格列数
void QTableWidget::setColumnCount(int columns)
// 设置表格行数
void QTableWidget::setRowCount(int rows)
// 获取表格列数
int QTableWidget::columnCount() const
// 获取表格行数
int QTableWidget::rowCount() const

2.2、添加单元格

// 添加单元格
void QTableWidget::setItem(int row, int column, QTableWidgetItem *item)
// 合并单元格
void QTableView::setSpan(int row, int column, int rowSpanCount, int columnSpanCount)
// 清除单元格(包含表头)
void QTableWidget::clear()
// 清除单元格内容(不包含表头)
void QTableWidget::clearContents()

2.3、表头设置

/**************************** 水平表头设置 *****************************/
// 设置表头单元格
void QTableWidget::setHorizontalHeaderItem(int column, QTableWidgetItem *item)
// 设置表头显示的文本信息
void QTableWidget::setHorizontalHeaderLabels(const QStringList &labels)
// 获取表头单元格
QTableWidgetItem* QTableWidget::horizontalHeaderItem(int column) const

/**************************** 垂直表头设置 *****************************/
// 设置表头单元格
void QTableWidget::setVerticalHeaderItem(int row, QTableWidgetItem *item)
// 设置表头显示的文本信息
void QTableWidget::setVerticalHeaderLabels(const QStringList &labels)
// 获取表头单元格
QTableWidgetItem* QTableWidget::verticalHeaderItem(int row) const

2.4、设置行表头、列表头是否显示

/**************************** 行表头视图 *****************************/
// 获取行表头视图
QHeaderView *QTableView::horizontalHeader()

// 隐藏行表头
virtual void QWidget::setVisible(bool visible)

/**************************** 列表头视图 *****************************/
// 获取列表头视图
QHeaderView *QTableView::verticalHeader() 

// 隐藏列表头
virtual void QWidget::setVisible(bool visible)

2.5、设置选择行为

void QAbstractItemView::setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
enum QAbstractItemView::SelectionBehavior 功能
QAbstractItemView::SelectItems 选中单个单元格
QAbstractItemView::SelectRows 行选中
QAbstractItemView::SelectColumns 列选中

2.6、设置单元格控件

QTableWidget不仅允许把文字加到单元格,还允许把控件也放到单元格中

// 获取单元格控件
QWidget *QTableWidget::cellWidget(int row, int column)

// 设置单元格控件
void QTableWidget::setCellWidget(int row, int column, QWidget *widget)

2.7、信号

下面是QTableWidget常用的信号,如下:

// 当item对应的data发生变化时,触发下面的信号
void QTableWidget::cellChanged(int row, int column)
// 双击单元格触发下面的信号
void QTableWidget::cellDoubleClicked(int row, int column)

3、QTableWidget代理

3.1、设置代理

可以给QTableWidget设置代理,通过代理能够自定义数据条目(item)的显示和编辑方式,QTableWidget提供的设置代理相关的方法如下:

// 给表格设置代理
void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate)
// 给列设置代理
void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelegate *delegate)
// 给行设置代理
void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *delegate)

注意 :只能给行、列、表格设置代理,不能给单个单元格设置代理

下面是Demo的截图,具体源码可以参考3.3

Qt编程基础 | 第六章-窗体 | 6.3、QTableWidget,Qt 编程基础,qt,开发语言

3.2、设置模型数据

QTableWidget默认使用的模型是QStandardItemModel,QTableWidget的每个单元格是一个QTableWidgetItem对象、Item、Delegate、Model三者间的数据交互关系如下:

Qt编程基础 | 第六章-窗体 | 6.3、QTableWidget,Qt 编程基础,qt,开发语言

// QModelIndex提供的获取模型的方法
const QAbstractItemModel *QModelIndex::model() const

// QTableWidgetItem提供的操作数据的方法
QVariant QTableWidgetItem::data(int role) const
void QTableWidgetItem::setData(int role, const QVariant &value)

// QAbstractItemModel提供的操作数据的方法
QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)

注意:调用QTableWidgetItem::setData设置的数据,最终是设置到Model里面了,这一点Demo里面的onCliecked槽函数有验证文章来源地址https://www.toymoban.com/news/detail-547228.html

3.3、代理触发时机

3.4、示例

// qcustomwidget.h
#ifndef QCUSTOMWIDGET_H
#define QCUSTOMWIDGET_H

#include <QWidget>
#include <QTableWidget>
#include <QStyledItemDelegate>
#include <QObject>
#include <QPushButton>

struct RowData
{
    QString name;
    QString age;
    QString sex;
    QString number;
};

class LineEditDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    explicit LineEditDelegate(QObject* parent = nullptr);
    ~LineEditDelegate();

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
    void setEditorData(QWidget* editor, const QModelIndex& index) const override;
    void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;

private:
    QTableWidget *m_pTableWidget;
};

class ComboBoxDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    explicit ComboBoxDelegate(QObject* parent = nullptr);
    ~ComboBoxDelegate();

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
    void setEditorData(QWidget* editor, const QModelIndex& index) const override;
    void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;

private:
    QTableWidget *m_pTableWidget;
};


// 之所以要继承QTableWidget,是因为QTableWidget::indexFromItem方法是Protected,外面无法访问,继承QTableWidget,可以重新提供一个接口GetIndexFromItem
// 根据item获取对应的QModelIndex

// 主要是为了验证一个问题点:调用item->setData,会影响QTableWidget对应的model,即:item->setData设置的数据,会直接设置到model里面
class QMyTableWidget : public QTableWidget
{
    Q_OBJECT

public:
    QMyTableWidget(QWidget *parent = 0);

    QMyTableWidget(int rows, int columns, QWidget *parent = Q_NULLPTR);

    QModelIndex GetIndexFromItem(QTableWidgetItem *item) const;
};

class QCustomWidget : public QWidget
{
    Q_OBJECT

public:
    QCustomWidget(QWidget *parent = 0);
    ~QCustomWidget();

public:
    void Init();

private:
    // 创建控件
    void CreateWidgets();

    // 给控件添加布局
    void CreateLayout();

    // 初始化表格样式
    void InitTableStyle();

    // 初始化表格内容
    void InitTableContent();

    // 初始化表格显示的数据
    void InitTableData();

    // 初始化表格代理
    void InitTableDelegate();

public slots:
    void OnCliecked();
    void OnCellChanged(int row, int column);
    void OnCellDoubleClicked(int row, int column);


private:
    QMyTableWidget *m_pTableWidget;
    QPushButton *m_pPushButton;
    std::vector<RowData> m_rowData;
};

#endif // QCUSTOMWIDGET_H

// qcustomwidget.cpp
#include "qcustomwidget.h"

#include <QStringList>
#include <QHeaderView>
#include <QHBoxLayout>
#include <QComboBox>
#include <QLineEdit>
#include <QMetaObject>
#include <QPushButton>
#include <QDebug>

const int MAX_COLUMN_SIZE = 4;

/**************************************************************************/
/* LineEditDelegate 代理 */
/**************************************************************************/
LineEditDelegate::LineEditDelegate(QObject* parent) : QStyledItemDelegate(parent)
{
    m_pTableWidget = qobject_cast<QTableWidget*>(parent);
}

LineEditDelegate::~LineEditDelegate()
{
}

QWidget* LineEditDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QLineEdit *editor = new QLineEdit(parent);
    return editor;
}

void LineEditDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
    QString text = index.model()->data(index, Qt::UserRole).toString();
    double value = floor((text.toDouble() * pow(10, 3) + 0.5)) / pow(10, 3);

    // 单元格设置修改的值时,会修改Qt::EditRole角色存储的数据,通过下面的打印可以很清楚地证明这一点
    QString strText = QString::number(value, 'f', 3);
    m_pTableWidget->item(index.row(), index.column())->setText(strText);

    qDebug() << "setEditorData data(Qt::EditRole) = " << m_pTableWidget->item(index.row(), index.column())->data(Qt::EditRole);
    qDebug() << "setEditorData data(Qt::UserRole) = " << m_pTableWidget->item(index.row(), index.column())->data(Qt::UserRole);

    QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(editor);
    pLineEdit->setText(text);
}

void LineEditDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
    QLineEdit* pLineEdit = qobject_cast<QLineEdit*>(editor);
    QString text = pLineEdit->text();

    model->setData(index, text, Qt::UserRole);
}

/**************************************************************************/
/* ComboBoxDelegate 代理 */
/**************************************************************************/
ComboBoxDelegate::ComboBoxDelegate(QObject* parent) : QStyledItemDelegate(parent)
{
    m_pTableWidget = qobject_cast<QTableWidget*>(parent);
}

ComboBoxDelegate::~ComboBoxDelegate()
{
}

QWidget* ComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    QComboBox *editor = new QComboBox(parent);
    editor->addItem(QString::fromLocal8Bit("男"));
    editor->addItem(QString::fromLocal8Bit("女"));
    editor->setCurrentIndex(0);
    return editor;
}

void ComboBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
    QComboBox* pComboBox = qobject_cast<QComboBox*>(editor);
    QString text = index.model()->data(index, Qt::EditRole).toString();

    int nIndex = pComboBox->findText(text);
    pComboBox->setCurrentIndex(nIndex);

    return;
}

void ComboBoxDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
    QComboBox* pComboBox = qobject_cast<QComboBox*>(editor);
    QString text = pComboBox->currentText();

    model->setData(index, text, Qt::EditRole);
}

/**************************************************************************/
/* QMyTableWidget 类实现 */
/**************************************************************************/
QMyTableWidget::QMyTableWidget(QWidget *parent) : QTableWidget(parent)
{

}

QMyTableWidget::QMyTableWidget(int rows, int columns, QWidget *parent) : QTableWidget(rows, columns, parent)
{

}

QModelIndex QMyTableWidget::GetIndexFromItem(QTableWidgetItem *item) const
{
    return indexFromItem(item);
}

/**************************************************************************/
/* QCustomWidget 类实现 */
/**************************************************************************/
void QCustomWidget::OnCliecked()
{
//    QTableWidgetItem *item = m_pTableWidget->item(1, 1);
//    item->setData(Qt::EditRole, QVariant(QString("123")));

//    QModelIndex index = m_pTableWidget->GetIndexFromItem(item);
//    QVariant data = index.model()->data(index, Qt::EditRole);

//    qDebug() << data.toString();
}


QCustomWidget::QCustomWidget(QWidget *parent) : QWidget(parent)
{
    // 设置QWidget对应的背景色
    setStyleSheet("background-color:yellow;");

    Init();
}

QCustomWidget::~QCustomWidget()
{
    qDebug() << "QCustomWidget Destroy";
}

void QCustomWidget::Init()
{
    CreateWidgets();

    CreateLayout();

    InitTableData();

    InitTableContent();

    InitTableStyle();

    InitTableDelegate();

    connect(m_pPushButton, SIGNAL(clicked()), this, SLOT(OnCliecked()));
    connect(m_pTableWidget, SIGNAL(cellChanged(int, int)), this, SLOT(OnCellChanged(int, int)));
    connect(m_pTableWidget, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(OnCellDoubleClicked(int, int)));
}

void QCustomWidget::InitTableStyle()
{
    // 设置表格占满父窗口
    m_pTableWidget->setAutoFillBackground(true);
    // 设置表格行选中
//    m_pTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    // 表格大小自适应父窗口变化
    m_pTableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    // 设置每列的宽度自适应窗口变化
    m_pTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    // 设置行表头不能被选中
    m_pTableWidget->horizontalHeader()->setSelectionMode(QAbstractItemView::NoSelection);
    // 隐藏列表头
    m_pTableWidget->verticalHeader()->hide();
    // 设置不显示表格线
//    m_pTableWidget->setShowGrid(false);
    // 设置右键下拉菜单样式
    m_pTableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
}

void QCustomWidget::InitTableData()
{
    RowData data1 = {QString("Jams"), QString("20"), QString::fromLocal8Bit("男"), QString("123456789")};
    RowData data2 = {QString("Messi"), QString("20"), QString::fromLocal8Bit("男"), QString("123456789")};
    RowData data3 = {QString("Luccy"), QString("20"), QString::fromLocal8Bit("男"), QString("123456789")};

    m_rowData.push_back(data1);
    m_rowData.push_back(data2);
    m_rowData.push_back(data3);
}

void QCustomWidget::InitTableContent()
{
    for (int row = 0; row < m_rowData.size(); row ++)
    {
        // 注意:如果不设置行数,表格的内容显示不出来
        m_pTableWidget->setRowCount(m_pTableWidget->rowCount() + 1);

        for (int col = 0; col < MAX_COLUMN_SIZE; col ++)
        {
            QTableWidgetItem* pTableWidgetItemItem = new QTableWidgetItem;
            switch(col)
            {
            case 0:
                pTableWidgetItemItem->setText(m_rowData[row].name);
                break;
            case 1:
                pTableWidgetItemItem->setText(m_rowData[row].age);
                break;
            case 2:
                pTableWidgetItemItem->setText(m_rowData[row].sex);
                break;
            case 3:
                pTableWidgetItemItem->setText(m_rowData[row].number);
                break;
            default:
                break;
            }
            m_pTableWidget->setItem(row, col, pTableWidgetItemItem);
        }
    }
}

void QCustomWidget::InitTableDelegate()
{
    m_pTableWidget->setItemDelegateForColumn(1, new LineEditDelegate(m_pTableWidget));
    m_pTableWidget->setItemDelegateForColumn(2, new ComboBoxDelegate(m_pTableWidget));
}

void QCustomWidget::CreateWidgets()
{
    // 创建按键
    m_pPushButton = new QPushButton(QString::fromLocal8Bit("调试"), this);
    m_pPushButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    // 创建QTableWidget
    m_pTableWidget = new QMyTableWidget(0, 4, this);

    // 设置表头
    QStringList labels;
    labels << QString::fromLocal8Bit("姓名");
    labels << QString::fromLocal8Bit("年龄");
    labels << QString::fromLocal8Bit("性别");
    labels << QString::fromLocal8Bit("手机号");
    m_pTableWidget->setHorizontalHeaderLabels(labels);
}

void QCustomWidget::CreateLayout()
{
    QVBoxLayout *pLayout = new QVBoxLayout();

    pLayout->addWidget(m_pTableWidget);
    pLayout->addWidget(m_pPushButton);

    setLayout(pLayout);
}

void QCustomWidget::OnCellChanged(int row, int column)
{
    qDebug() << "CellChanged row = " << row << ", column = " << column;
}

void QCustomWidget::OnCellDoubleClicked(int row, int column)
{
    qDebug() << "CellDoubleClicked row = " << row << ", column = " << column;
}

到了这里,关于Qt编程基础 | 第六章-窗体 | 6.3、QTableWidget的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《TCP IP网络编程》第六章

    UDP 套接字的特点:         通过寄信来说明 UDP 的工作原理,这是讲解 UDP 时使用的传统示例,它与 UDP 的特点完全相同。寄信前应先在信封上填好寄信人和收信人的地址,之后贴上邮票放进邮筒即可。当 然,信件的特点使我们无法确认信件是否被收到。邮寄过程中也可能

    2024年02月16日
    浏览(53)
  • java JUC并发编程 第六章 CAS

    第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 第六章 java JUC并发编程 CAS: link 第七章 java JUC并发编程 原子操作类增强: link 第八章

    2024年02月10日
    浏览(48)
  • 《Python程序设计》 第六章 函数+编程题解

    目录 6-1 使用函数求特殊a串数列和 6-2 使用函数求素数和 6-3 使用函数统计指定数字的个数 6-4 使用函数输出指定范围内Fibonacci数的个数  6-5 使用函数求余弦函数的近似值 6-6 缩写词 7-1 输入列表,求列表元素和(eval输入应用) 7-2 一帮一 7-3 验证“哥德巴赫猜想” 7-4 列表或元组

    2024年02月07日
    浏览(67)
  • C Primer Plus第六章编程练习答案

    学完C语言之后,我就去阅读《C Primer Plus》这本经典的C语言书籍,对每一章的编程练习题都做了相关的解答,仅仅代表着我个人的解答思路,如有错误,请各位大佬帮忙点出! 1.编写一个程序,创建一个包含26个元素的数组,并在其中储存26个小 写字母。然后打印数组的所有

    2024年02月06日
    浏览(44)
  • 曲线艺术编程 coding curves 第六章 平托图 (Pintographs)

    原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) blog: http://cnblogs.com/willian/ 源码:github: https://github.com/willian12345/coding-curves 曲线艺术编程系列第 6 章 另一个可用于模拟绘制复杂曲线的物理装置叫平托图(Pintograph), 事实上我真的自己弄了一个。

    2024年02月08日
    浏览(43)
  • 第六章——Unity中的基础光照

    原理在games101中讲的很清楚,就不赘述了,可以看参考里的games101。 主要是光照模型在Unity中的实现。 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象。 1、首先,光线从光源(light source)中被发射出来。 2、然后,光线和场景中的一些物体相交

    2024年01月22日
    浏览(46)
  • 计算机网络基础第六章

    1.1.1 客户/服务器(C/S)模型 1.1.2 P2P模型 网际报文存取协议IMAP 5.2.1 HTTP协议的特点 5.2.2 HTTP协议的连接方式 5.2.3 超文本传输协议HTTP-报文结构

    2024年02月16日
    浏览(44)
  • 【软考数据库】第六章 数据库技术基础

    目录 6.1 基本概念 6.1.1 关于数据的基本概念 6.1.2 数据库管理系统的功能 6.1.3 数据各个发展阶段的特点 6.1.4 数据库系统的体系结构 6.2 数据模型 6.2.1 三级模式两级映像 6.2.2 数据模型_模型分类 6.2.3 数据模型_组成要素 6.2.4 概念模型中的基本概念 6.2.5 数据模型 6.3 数据存储与查

    2024年02月05日
    浏览(56)
  • Unity Shader入门精要 第六章——Unity中的基础光照

    目录 一、标准光照模型(Phong光照模型) 1、环境光  2、自发光 3、漫反射 4、高光反射 (1)Phong模型 (2)Blinn模型 5、光照模型实现方法——逐顶点和逐像素 二、Unity Shader 漫反射光照模型的实现 1、实践:逐顶点 2、实践:逐像素 3、半兰伯特模型 4、漫反射光照模型效果展

    2024年02月04日
    浏览(50)
  • 黑马程序员Java基础入门第三版第六章

    单选题 1、 正则表达式中表示单词边界的元字符是() 2分 A、A、A B、B、G C、C、B D、D、b 参考答案 : D 答案说明 : 无 2、 下列关于LocalTime类与LocalDateTime类的描述错误的的是() 2分 A、A、LocalTime类能代表时间线上的即时信息。 B、B、LocalDateTime类是LocalDate类与LocalTime类的综

    2024年02月06日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包