Qt开发之QTableWidget

QTableWidget从继承QTableView,实质属于模型-视图范畴之内,只是带了默认模型(model)基于项目(item)的表格视图控件。我们不需要实现model内的数据加工。QTableWidget为应用程序提供了标准的表显示工具。QTableWidget中的项目(item)是由QTableWidgetItem来实现。QTableWidget各种属性可利用Qt自带的UI设计师来设置,如下图:

接下来我们定制 2行4列的表格视图。主要的代码 setRowCount,setColumnCount,setHorizontalHeaderLabels,setItem完成一个数据的填充。

    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置表格不能编辑
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->verticalHeader()->setVisible(false);  //去除左右的列序号
    ui->tableWidget->setStyleSheet("QHeaderView::section { border:none; height:30px;color:#555555;background:#F2F5F8;}QTableView::item:selected{background:#87CEFA;}");
    ui->tableWidget->horizontalHeader()->setVisible(true); //去除表头
    ui->tableWidget->setShowGrid(true); //设置显示格子线
    ui->tableWidget->setColumnCount(4);//设置4列
    ui->tableWidget->setColumnWidth(0, 111);
    ui->tableWidget->setColumnWidth(1, 111);
    ui->tableWidget->setColumnWidth(2, 111);
    ui->tableWidget->setColumnWidth(3, 111);
    ui->tableWidget->setRowCount(2);//设置2行
    ui->tableWidget->horizontalHeader()->setFixedHeight(30); //表头高度
    ui->tableWidget->verticalHeader()->setDefaultSectionSize(28); //设置表格行高
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    QStringList headerText;
    headerText<< tr("类型1")<< tr("类型2") << tr("类型3") << tr("类型4"); //表头标题用QStringList来表示
    ui->tableWidget->setHorizontalHeaderLabels(headerText); 
    ui->tableWidget->setColumnCount(headerText.count());//列数设置为与 headerText的行数相等
    
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);//固定表头
    ui->tableWidget->horizontalHeader()->setSectionsClickable(false);
    for (int row = 0; row < ui->tableWidget.rowCount(); ++row) 
    {
        for (int col = 0; col < ui->tableWidget->columnCount(); ++col) 
        {
            switch (col) 
            {
            case 0:
                item = new QTableWidgetItem("语文");
                break;
            case 1:
                item = new QTableWidgetItem("数学");
                break;
            case 2:
                item = new QTableWidgetItem("英语");
                item->setTextColor(QColor(57, 125, 238));
                break;
            case 3:
                item = new QTableWidgetItem("物理");
                item->setTextColor(QColor(57, 125, 238));
                break;
            }
            item->setTextAlignment(Qt::AlignCenter);//文本对齐格式
            ui->tableWidget->setItem(row,col,item);//为单元格设置Item
        }
        row++;
    }

操作起来很简单,但是在实际的业务场景中,我们更希望的是能从每一项获得业务数据模型,使用 QTableWidgetItem中的setData()方法。假设自定义业务模型类:class iteminfo

iteminfo k;
QVariant vart;
vart.setValue(k);
QTableWidgetItem *item = new QTableWidgetItem();
item->setData(Qt::UserRole,vart);

获取数据
item->data(Qt::UserRole).value<iteminfo>();

这边涉及到了两点,第一,业务数据模型,是人为自定义,所以需要向Qt 元对象系统(Meta-Object)申明该类型,Q_DECLARE_METATYPE(iteminfo),添加Q_DECLARE_METATYPE()宏将使所有基于模板的函数(包括QVariant)都知道该类型。注意,如果打算在队列信号和槽连接或QObject的属性系统中使用该类型,还必须在构造函数中调用qRegisterMetaType("iteminfo")函数,因为名称是在运行时解析的。

UI样式优化

在开发过程中 在用户体验上有些瑕疵,就是当选中某一行时,选中项出现虚线框并且某些项字体带有颜色的全消失了都恢复了默认颜色(黑色)。使用qss修改样式由于数据本身的颜色可以发生变化。所以不适合使用。这里使用QStyledItemDelegate(代理)的方式

#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H

#include <QStyledItemDelegate>

class ItemDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    ItemDelegate(QObject *parent = nullptr);
    virtual void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
};

#endif // ITEMDELEGATE_H

#include "itemdelegate.h"
#include "style/theme.h"
#include <QPainter>

ItemDelegate::ItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
    
}

void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem  viewOption(option); 
    if (viewOption.state & QStyle::State_Selected)
    {
        painter->fillRect(viewOption.rect, QBrush(UI_SELECTTIEM_COLOR));
         viewOption.state = viewOption.state & 0;//去掉选中时的虚线框
    }
    else
    {
        if (index.row() % 2 == 0)
        {
            painter->fillRect(viewOption.rect, QBrush(UI_EVENROW_COLOR));
        }
        else
        {
            painter->fillRect(viewOption.rect, QBrush(UI_ODDROW_COLOR));
        }
        if (viewOption.state & QStyle::State_HasFocus) {//去掉虚线框
            viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
        }
    }
    paintItemData(painter, viewOption, index.data(Qt::UserRole));
    //如何做得通用 每个view 都有基础样式比如:交替变化色,悬浮色,选中色等
    //再构造一个虚函数 子类化该基础样式
    
    //高亮显示与普通显示时的前景色一致(即选中行和为选中时候的文字颜色一样)  
    viewOption.palette.setColor(QPalette::HighlightedText, index.data(Qt::ForegroundRole).value<QColor>());  
    //viewOption.palette.setColor(QPalette::Foreground, UI_SELECTTIEM_COLOR);  
    QStyledItemDelegate::paint(painter, viewOption, index);
}

结果如下图所示:

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值