QTableWidget——单元格的复制、粘贴、还原

发布时间:2023年12月17日

一、复制、粘贴的分类

QTableWidget单元格的内容:
主要实现单个单元格、整行、整列、多个单元格的复制粘贴
对于文本内容
主要实现内容与样式的复制粘贴
对于公式、日期、数字
实现内容递增、样式的复制粘贴

二、效果展示

1、文本内容单个单元格的复制粘贴

粘贴前
在这里插入图片描述

粘贴后
在这里插入图片描述

2、文本内容整行的复制粘贴

粘贴前
在这里插入图片描述
粘贴后
在这里插入图片描述

三、主要代码

1、文本内容单个单元格的复制粘贴

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "citemtypedialog.h"
#include <QMessageBox>
#include <QDebug>
#include<QKeyEvent>
using namespace std;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_table = new QTableWidget(this);
    m_table->setGeometry(10,10,800,450);
    m_table->setRowCount(5);
    m_table->setColumnCount(6);
    m_table->setContextMenuPolicy(Qt::CustomContextMenu);
    m_table->installEventFilter(this);
    m_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    readTableData();
    createMenu();
    connect(m_table, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCellOperateMenu(QPoint)));
    connect(m_table,SIGNAL(itemDoubleClicked(QTableWidgetItem *)),this,SLOT(onItemDoubleClicked(QTableWidgetItem *)));
}

void MainWindow::createMenu()
{
    m_menu = new QMenu;
    m_menu->addAction(QString::fromLocal8Bit("合并单元格"), this, &MainWindow::onSpanCell);
    m_menu->addAction(QString::fromLocal8Bit("拆分单元格"), this, &MainWindow::onSplitCell);
    m_menu->addAction(QString::fromLocal8Bit("复制"), this, &MainWindow::onCopy);
    m_menu->addAction(QString::fromLocal8Bit("粘贴"), this, &MainWindow::onPaste);
    m_menu->addAction(QString::fromLocal8Bit("设置"), this, &MainWindow::onSet);
}

void MainWindow::createTable()
{
    int rowNum = m_table->rowCount();
    int colNum = m_table->columnCount();
    m_table->setRowCount(0);
    m_table->setColumnCount(0);

    m_table->setRowCount(rowNum);
    m_table->setColumnCount(colNum);

    for(auto& pRowInfro:m_tableInfor)
    {
        for(auto& pCol:pRowInfro.second)
        {
            if(pCol.second->rowSpan > 0||pCol.second->colSpan > 0)
            {
                m_table->setSpan(pCol.second->row, pCol.second->col, pCol.second->rowSpan , pCol.second->colSpan);
            }

            QTableWidgetItem * pItem = new QTableWidgetItem(pCol.second->data);
            QString str = QString::fromUtf8(pCol.second->style);
            QFont font;
            if (!(str.isEmpty()))
            {
               pItem->setText(pCol.second->data);

                // 设置单元格样式
                QStringList stylelist = str.split(",");
                font.setFamily(stylelist.at(0));
                font.setPointSize(stylelist.at(1).toInt());
                font.setBold(stylelist.at(2).toInt());
                pItem->setFont(font);
                QColor color(stylelist.at(3));
                pItem->setForeground(color);

                QColor bgdcolor(stylelist.at(4));
                QBrush Brush(bgdcolor);
                Brush.setStyle(Qt::SolidPattern);
                pItem->setBackground(Brush);
            }
            m_table->setItem(pCol.second->row, pCol.second->col,pItem);
        }
    }
}

void MainWindow::readTableData()
{
    int row;
    TableItemInfor* infor;
    for(row = 0;row< 5;row++)
    {
        std::map<int,TableItemInfor*> inforMap;
        for(int col = 0; col< 6;col++)
        {
            infor = new TableItemInfor;
            QString text = QString::number(col);
            infor->row = row;
            infor->col = col;
            infor->data = "";
            inforMap.insert(std::make_pair(col, infor));
        }
        m_tableInfor.insert(std::make_pair(row, inforMap));
    }
    createTable();
}

void MainWindow::onSpanCell()
{
    QModelIndexList list = m_table->selectionModel()->selectedIndexes();
    if (list.size() < 2)
    {
        QMessageBox::warning(this, "单元格合并", "所选中单元格中为单个单元格,无法合并", "确定");
        return;
    }

    int minRow = 0;
    int maxRow = 0;
    int minCol = 0;
    int maxCol = 0;

    QList<QTableWidgetSelectionRange> vec = m_table->selectedRanges();

    if (vec.size() > 0)
    {
        minRow = vec[0].topRow();
        maxRow = vec[0].topRow();
        minCol = vec[0].leftColumn();
        maxCol = vec[0].rightColumn();
    }

    for (auto v : vec)
    {
        if (minRow > v.topRow())
        {
            minRow = v.topRow();
        }
        if (maxRow < v.bottomRow())
        {
            maxRow = v.bottomRow();
        }

        if (minCol > v.leftColumn())
        {
            minCol = v.leftColumn();
        }
        if (maxCol < v.rightColumn())
        {
            maxCol = v.rightColumn();
        }
    }

    int rowSpan = (maxRow - minRow) + 1;
    int colSpan = (maxCol - minCol) + 1;
    m_table->setSpan(minRow, minCol, rowSpan, colSpan);
    for(auto& pRowInfro:m_tableInfor)
    {
        if(pRowInfro.first==minRow)
        {
            for(auto& pColInfro:pRowInfro.second)
            {
                if(pColInfro.first==minCol)
                {
                    pColInfro.second->rowSpan = rowSpan;
                    pColInfro.second->colSpan = colSpan;
                }
            }
        }
    }
    //m_table->setCurrentCell(minRow, minCol,QItemSelectionModel::Deselect);
    m_table->setCurrentCell(minRow, minCol,QItemSelectionModel::Select);
}

void MainWindow::onSplitCell()
{
    qDebug()<< m_table->currentRow()<< m_table->currentColumn();
    QList<QTableWidgetSelectionRange> vec = m_table->selectedRanges();
    if (vec.size() < 2)
    {
        QMessageBox::warning(this, QString::fromLocal8Bit("拆分表格失败"), QString::fromLocal8Bit("单元格已是最小单元,不可再进行拆分"), QString::fromLocal8Bit("确定"));
        return;
    }
    int row,col;
    for (auto i : vec)
    {
        row = i.topRow();
        col = i.leftColumn();
        for(auto& pRowInfro:m_tableInfor)
        {
            if( pRowInfro.first == row )
            {
                for(auto& pColInfro:pRowInfro.second)
                {
                    if(pColInfro.first == col)
                    {
                        pColInfro.second->rowSpan = 0;
                        pColInfro.second->colSpan = 0;
                    }
                }
            }
        }
    }
    createTable();
}

void MainWindow::onCellOperateMenu(QPoint p)
{
    m_menu->exec(QCursor::pos());
}

void MainWindow::onCopy()
{
    m_cpyInfor.clear();
    //获取选中信息
    QList<QTableWidgetSelectionRange> tableList = m_table->selectedRanges();
    if(tableList.size() <= 0)
    {
        return;
    }

     int colNum;    //列号
     int rowNum;    //行号
    //判断选择的数量、行、列
    if(1 == tableList.size())
    {
        colNum = tableList.at(0).leftColumn();
        rowNum = tableList.at(0).topRow();

        //获取单元个内容
      TableItemInfor* infor = m_tableInfor[rowNum][colNum];
       if(!infor)
       {
           return;
       }
      m_cpyInfor.push_back(infor);
    }

    qDebug()<<"onCopy";
}

void MainWindow::onPaste()
{
    int curRow = m_table->currentRow();
    int curCol = m_table->currentColumn();

    if(m_cpyInfor.size() > 1)
    {
        //暂时只处理单个内容复制
        return;
    }
    //修改原有内容
    m_tableInfor[curRow][curCol]->data = m_cpyInfor[0]->data;

    memcpy(m_tableInfor[curRow][curCol]->style,m_cpyInfor[0]->style,sizeof(m_cpyInfor[0]->style));
    m_tableInfor[curRow][curCol]->colSpan = m_cpyInfor[0]->colSpan;
    m_tableInfor[curRow][curCol]->rowSpan = m_cpyInfor[0]->rowSpan;
    createTable();
    qDebug()<<"onPaste";
}

void MainWindow::onRestore()
{
    qDebug()<<"onRestore";
}

void MainWindow::onSet()
{
    int row = m_table->currentRow();
    int col = m_table->currentColumn();
    TableItemInfor* pItemInfo = m_tableInfor.at(row).at(col);
    CItemTypeDialog dlg;
    QFont font;
    dlg.setType(pItemInfo);
    if (QDialog::Accepted == dlg.exec())
    {
        QString str = QString::fromUtf8(pItemInfo->style);
        if (!(str.isEmpty()))
        {
           QTableWidgetItem *pTableWidgetItem = m_table->currentItem();
           pTableWidgetItem->setText(pItemInfo->data);
            // 设置单元格样式
            QStringList stylelist = str.split(",");
            font.setFamily(stylelist.at(0));
            font.setPointSize(stylelist.at(1).toInt());
            font.setBold(stylelist.at(2).toInt());
            pTableWidgetItem->setFont(font);
            QColor color(stylelist.at(3));
            pTableWidgetItem->setForeground(color);

            QColor bgdcolor(stylelist.at(4));
            QBrush Brush(bgdcolor);
            Brush.setStyle(Qt::SolidPattern);
            pTableWidgetItem->setBackground(Brush);
            QString style = font.styleName() ;
        }
    }
}

void MainWindow::onItemDoubleClicked(QTableWidgetItem *item)
{

     onSet();
}

bool MainWindow::eventFilter(QObject *pObj, QEvent *pEvent)
{
    if (pObj == m_table)
    {
        if (pEvent->type() == QEvent::KeyPress)
        {
            QKeyEvent* keyEvent = static_cast<QKeyEvent*>(pEvent);

            if (keyEvent->modifiers() == Qt::ControlModifier)
            {
                if (keyEvent->key() == Qt::Key_C)
                {
                    onCopy();
                    return true;
                }
                else if (keyEvent->key() == Qt::Key_V)
                {
                    onPaste();
                    return true;
                }
                else if (keyEvent->key() == Qt::Key_Z)
                {
                    onRestore();
                    return true;
                }

            }
        }
    }
    return QObject::eventFilter(pObj, pEvent);;
}

2、文本内容整行内容的复制粘贴(一行)

void MainWindow::onCopy()
{
    m_cpyInfor.clear();
    //获取选中信息
    QList<QTableWidgetSelectionRange> tableList = m_table->selectedRanges();
    if(tableList.size() <= 0)
    {
        return;
    }

     int colNum;    //列号
     int rowNum;    //行号
     int rowCount,colCount,currentRow;
     QList <TableItemInfor*> itemInfor;

    //判断选择的数量、行、列
    if(1 == tableList.size())
    {
        //判断单个单元格和一整行
        if(1 == tableList.at(0).rowCount() && tableList.at(0).columnCount() > 1)
        {
            m_cpyType = 0;
            rowCount = tableList.at(0).rowCount();

            //计算选中的总列数
            colCount = tableList.at(0).columnCount();
            currentRow = tableList.at(0).topRow();

            //获取相应的项数据
            for (int i = 0; i < colCount; i++)
            {
                TableItemInfor* infor;
                infor = m_tableInfor[currentRow][i];

                //合并列处理
                if (((i + 1) + infor->colSpan) >= colCount)
                {

                   itemInfor.push_back(infor);
                    break;
                }
               itemInfor.push_back(infor);
            }
             m_cpyInfor.insert(make_pair(m_cpyType,itemInfor));
        }
        else
        {
            m_cpyType = 2;
            colNum = tableList.at(0).leftColumn();
            rowNum = tableList.at(0).topRow();

            //获取单元个内容
            TableItemInfor* infor = m_tableInfor[rowNum][colNum];
            if(!infor)
            {
                return;
            }
            itemInfor.push_back(infor);
            m_cpyInfor.insert(make_pair(m_cpyType,itemInfor));
        }
    }

    qDebug()<<"onCopy";
}

void MainWindow::onPaste()
{
    int curRow = m_table->currentRow();
    int curCol = m_table->currentColumn();

    if(m_cpyInfor.size() > 1)
    {
        //暂时只处理单个内容复制
        return;
    }

    for(auto& it:m_cpyInfor)
    {
        if( 0 == it.first)
        {
            for(auto& pItem:it.second)
            {
                curCol = pItem->col;
                m_tableInfor[curRow][curCol]->data = pItem->data;
                memcpy(m_tableInfor[curRow][curCol]->style,pItem->style,sizeof(pItem->style));
                m_tableInfor[curRow][curCol]->colSpan = pItem->colSpan;
                m_tableInfor[curRow][curCol]->rowSpan = pItem->rowSpan;
            }
        }
        else if(1 == it.first)
        {
            return;
        }
        else if(2 == it.first)
        {
            m_tableInfor[curRow][curCol]->data = it.second.at(0)->data;
            memcpy(m_tableInfor[curRow][curCol]->style,it.second.at(0)->style,sizeof(it.second.at(0)->style));
            m_tableInfor[curRow][curCol]->colSpan = it.second.at(0)->colSpan;
            m_tableInfor[curRow][curCol]->rowSpan = it.second.at(0)->rowSpan;
        }
    }

    createTable();
    qDebug()<<"onPaste";
}

四、视频效果展示

文本内容效果展示

文章来源:https://blog.csdn.net/qq_15672897/article/details/134768955
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。