QTableWidget实现类似excel表格选中数据右下角下拉内容递增的功能

3 篇文章 0 订阅
2 篇文章 0 订阅

QTableWidget实现类似excel表格选中数据右下角下拉内容递增的功能

在实际开发过程中QTableWidget这个控件时经常使用到的,在表格中需要使用大量相同或自增的数据时,手动输入变得不太现实,所以就需要类似excel表格那样的下拉内容自增的功能。
本人也是在工作的过程中遇到该问题,反复查找各种资源,浏览各大国内外网站都得不到解决,最后在深入QT底层查看代码后尝试得到该问题的解决方法,故此分享给大家,希望能有所帮助。
先上效果图:
下拉自增
通过上面的效果图,大家可以看到大致的实现了类似excel表格的下拉自增功能,当然能实现自增,当然可以实现复制,自减等等数学操作。

下面我们来分析实现该功能的具体实现方法:
1.首先是选中的外观,要想实现选中外观则需要对QTableWidget的ItemDelegate(QStyledItemDelegate&)函数进行设置,同时还需要重写QStyledItemDelegate来绘制选中矩形。
2.其次我们则是要对鼠标外观进行分析设置,要实现鼠标外观只有在移到选中框右下角矩形时才会变成特定的样式,则需要在鼠标点击时,获取鼠标点击的框的位置以及长宽用来计算出右下角矩形的位置,当鼠标移到计算位置的区域时,则鼠标样式改变。获取点击框的位置以及长宽在重写QStyledItemDelegate类时可以在paint()函数的参数QStyleOptionViewItem获取
3.当鼠标移到右下角矩形位置以及按下鼠标左键,进行移动则可将选中框内容进行自增、复制等操作

1.QStyledItemDelegate类重写

QStyledItemDelegate类是模型中的数据项提供显示和编辑工具,可以用来显示图形等操作。
核心函数
void paint(QPainter painter, const QStyleOptionViewItem & option, const QModelIndex &index) const;*
函数参数解析(个人理解):
QPainter:用于在各部件上绘制图形、文字、直线、矩形等图案的类
QStyleOptionViewItem:用于描述当前视图由QPainter绘制的各项参数,如:位置、长宽等参数。
QModelIndex:用于定位当前QPainter绘制的数据模型。

知道了函数参数的功能和各个参数的含义,我们就可以来绘制选中时的选中框了,选中框本人使用的5部分制作,如下图:
在这里插入图片描述
本人绘制的矩形框是由四条直线以及一个点所构成的,代码如下:

//绘制选中矩形函数,参数来源于QStyledItemDelegate类的QPainter函数,此函数在QPainter函数哦内阁制调用
void PainPressOrRelease(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const
{
	painter->setPen(QPen(QColor(31,187,125),4));//设置画笔的颜色以及粗细
	//绘制直线1
	painter->drawLine(QPointF(option.rect.x()+1,option.rect.y()+1), 	QPointF(option.rect.x()+option.rect.width()-1,option.rect.y()+1));
	//绘制直线2
	painter->drawLine(QPointF(option.rect.x()+1,option.rect.y()+1), QPointF(option.rect.x()+1,option.rect.y()+option.rect.height() - 1));
	//绘制直线3
	painter->drawLine(QPointF(option.rect.x()+1,option.rect.y()+ option.rect.height() - 1), QPointF(option.rect.x()+option.rect.width()-7,option.rect.y()+ option.rect.height() - 1));
	//绘制直线4
	painter->drawLine(QPointF(option.rect.x()+option.rect.width()-1,option.rect.y() + 1), QPointF(option.rect.x()+option.rect.width()-1,option.rect.y()+option.rect.height() - 7));
	//绘制右下角点
	painter->drawPoint(option.rect.x()+option.rect.width()-2,option.rect.y()+option.rect.height() - 2);
}

重写paint函数:

void MyNoFocusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
	if (option.state & QStyle::State_Selected)//此处为点击选中模式
    {
    	if(条件)//这里可以放其他限制条件
        {
        	PainPressOrRelease(painter,option,index);//调用画笔
        }
    }
    paintForegroundText(painter,option,index);//提交绘画的数据,本人是自己绘画
}

重写提交数据函数:
以便控件可以进行绘制,相当于告诉控件开始绘制内容

void paintForegroundText(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
	//设置画笔颜色为黑色,防止在用户输入数据时数据的颜色于展示的颜色不一致
    painter->setPen(QColor(0,0,0));
    QFontMetrics fontMetrics(painter->font());//获取画笔字体
    QString msg = fontMetrics.elidedText(index.data().toString(), Qt::ElideRight, option.rect.width());//获取要画的内容
    QRect myrect = option.rect;
    //由于本人画的选中框边框比较厚,所以需要移动5个位置,否则数据被边框挡住
    myrect.setLeft(option.rect.left() + 5);
    QApplication::style()->drawItemText(painter, myrect, option.displayAlignment, QApplication::palette(), true, msg);
}

2.重写QTableWidget

重写QTableWidget主要是重写QTableWidget的三个鼠标事件,分别为:
1.mouseMoveEvent鼠标移动捕获函数
2.mousePressEvent鼠标按下捕获函数
3.mouseReleaseEvent鼠标按下后松开捕获函数
重写mouseMoveEvent函数目的主要是便于在移动鼠标至选中框右下角的小矩形时,更换鼠标样式以及在右下角拖拽时检测数据和让数据递增。
重写mousePressEvent函数主要是捕获到当前按下鼠标的状态,用于识别是否进行数据递增。
重写mouseReleaseEvent函数主要是让模式重置

下面我们来看一下三个函数:
1.void mouseMoveEvent(QMouseEvent *event)

void mouseMoveEvent(QMouseEvent *event)
{
    QPoint mousePos =  event->pos();//获取鼠标位置信息

    if((mousePos.rx() >= (Namedata.x+Namedata.Widget -7) && mousePos.rx() <= (Namedata.x+Namedata.Widget)
            && mousePos.ry() >= (Namedata.y+Namedata.Hight-7) && mousePos.ry() <= (Namedata.y+Namedata.Hight))
            || isClick )//判断是否在我们规定的区域,或者是按下模式,isClick是按下模式标志
    {
        this->setCursor(Qt::SizeAllCursor);//设置鼠标在右下角区域样式
        isAdd = true;//在右下角区域
        if(Namedata.isPattern)//是否是按下拖拽模式
        {
        	//如果是按下拖拽模式,则对当前选中的item进行数据设置,本人此处ToAddString函数则是递增函数
            this->currentItem()->setText(ToAddString());
        }
    }
    else
    {
        isAdd = false;//不在右下角矩形范围内
        this->setCursor(Qt::ArrowCursor);      //范围之外变回原来形状

    }
    QTableWidget::mouseMoveEvent(event);//提交鼠标给QTableWidget控件,否则QTableWidget控件监测不到鼠标后以上代码则做无用功

}

2.void mousePressEvent(QMouseEvent *event)

void mousePressEvent(QMouseEvent *event)
{
	//确保按下的是鼠标左键且是在选中框右下角
    if(event->button()==Qt::LeftButton && isAdd)
    {
        this->setCursor(Qt::SizeAllCursor);//设置为鼠标样式,防止鼠标在拖动的过程中由于鼠标样式改变,导致数据设置失败
        isClick = true;//是左键按下模式
        Namedata.SetPress(isChecil);//将该模式传给其他类作数据交换
        //确保当前按下鼠标左键选中的单元格有内容,否则拖拽自增数据无效
        if(!this->currentIndex().data().isNull() && this->currentIndex().data().toString().size() > 0)
        {
            Namedata.Count = this->currentColumn() + 2;//本人的标志
            Namedata.isPattern = true;//是拖拽自增模式
        }
        else
            Namedata.Count = 1;
    }
    else
    {
        isClick = false;//不是左键按下模式
        this->setCursor(Qt::ArrowCursor);
    }

    QTableWidget::mousePressEvent(event);//提交鼠标给控件
}

3.void mouseReleaseEvent(QMouseEvent *event)

void mouseReleaseEvent(QMouseEvent *event)
{
    if(isChecil)//松开之前是按下模式,释放各种参数
    {
        isClick = false;
        Namedata.SetPress(isChecil);
        Namedata.Count = 0;
        Namedata.isAdd = false;
        Namedata.isPattern = false;
    }
    this->setCursor(Qt::ArrowCursor);//设置鼠标样式
    this->setCurrentIndex(Namedata.returnModelIndex());//将当前选择的单元格还给拖拽前点击的单元格
    QTableWidget::mouseReleaseEvent(event);//提交鼠标给控件
}

至此QTableWidget的鼠标事件重写完毕

以上为数据拖拽自增的全部过程。
源码下载地址:https://download.csdn.net/download/REDPINGPING/87554340

  • 14
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 36
    评论
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值