QTableWidget实现复制粘贴(初步修正)

文章详细描述了一个在QT环境中使用QTableWidget时遇到的复制粘贴bug,当单独复制一个单元格时,相邻单元格内容会被清空。作者提供了修复此问题的代码,修改了复制和粘贴的实现,确保正确处理单元格内容。此外,文章还讨论了可能存在的其他问题,如特殊字符影响复制粘贴,并提出了可能的解决方案,如清除非显示控制符或使用导入导出功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注意:

  1. 在cpp文件中包含: include <QClipboard>
  2. 在h文件中包含: QClipboard *clipboard;
  3. 下句的红色字体部分,需要根据实际修改
    sRangeList = ui->tableWidget->selectedRanges();
  4. 增加2个槽函数,分别调用它们。

Bug:

对整个表格进行复制和粘贴,则 OK。

单独对一个单元格进行复制,会将同行的下一个单元格的内容清空。

测试环境:与原作者的有所不同,因此,不能证明原来的 src就一定有问题??

改Bug:

                    if(p.leftColumn()==p.rightColumn())
                        rowStr = item->text() + "\n";
                    else if(j == p.leftColumn())

复制:

// 复制选中内容

// 2023/02:这个原文件似乎有bug,已经初步修正了。

void MainWidget::copySelectFromTable()
{
    QList<QTableWidgetSelectionRange> sRangeList = ui->tableWidget->selectedRanges();
    for(const auto &p : qAsConst(sRangeList)) {
        QString str;
        for (auto i = p.topRow(); i <= p.bottomRow(); i++) {
            QString rowStr;
            for (auto j = p.leftColumn(); j <= p.rightColumn(); j++) {
                QTableWidgetItem* item =  ui->tableWidget->item(i, j);
                if(item != nullptr) {
                    if(p.leftColumn()==p.rightColumn())  //新增
                        rowStr = item->text() + "\n";  //新增
                    else if(j == p.leftColumn())  //修改
                    // if(j == p.leftColumn())
                        rowStr = item->text() + "\t";
                    else if (j == p.rightColumn())
                        rowStr = rowStr + item->text() + "\n";
                    else
                        rowStr = rowStr + item->text() + "\t";
                }
                else {
                    break;
                }
            }
            str += rowStr;
        }
        clipboard= QApplication::clipboard();
        clipboard->setText(str);
    }
}

黏贴

// 粘贴,从选中的第一个单元格开始
void MainWidget::pasteToTable()
{
    QList<QTableWidgetSelectionRange> sRangeList = ui->tableWidget->selectedRanges();
    int allRow = ui->tableWidget->rowCount();
    int allCol = ui->tableWidget->columnCount();
    for(const auto &p : qAsConst(sRangeList)) {
        QString str = clipboard->text();
        int ColCnt = ui->tableWidget->columnCount();
        QList<QString> RowStr = str.split("\n");
        int copyAreaAllRow = RowStr.size();
        qDebug()<<"copyAreaAllRow"<<copyAreaAllRow;
        int x = p.topRow();
        int rightIndex = p.rightColumn();
        int surplusRow = allRow - x;
        int surplusCol = allCol - rightIndex;
        if((RowStr.size() -1) > surplusRow)//如果复制的行数大于剩余的行数,去除掉多余的赋值内容
        {
            int len = RowStr.size();
            for(int i=len -2;i>=surplusRow;i--)
            {
                RowStr.removeAt(i);
            }
        }
        for(const auto &Row : qAsConst(RowStr)) {
            if(!Row.isEmpty()) {
                QList<QString> ColStr = Row.split("\t");//赋值的列数
                if(ColStr.size() > surplusCol)//如果复制的列数大于剩余的列数,去除掉多余的赋值内容
                {
                    int len = ColStr.size();
                    for(int i=len -1;i>=surplusCol;i--)
                    {
                        ColStr.removeAt(i);
                    }
                }
                int y = p.leftColumn();
                for(const auto &Col : qAsConst(ColStr)) {
                    QTableWidgetItem* item = ui->tableWidget->item(x, y);
                    if(item == nullptr)
                    {
                        ui->tableWidget->setItem(x, y, new QTableWidgetItem(Col));
                        ui->tableWidget->item(x,y)->setForeground(QBrush(QColor(255,0,0)));
                    }
                    else 
                    {
                        ui->tableWidget->item(x, y)->setText(Col);
                        ui->tableWidget->item(x,y)->setForeground(QBrush(QColor(255,0,0)));
                    }
                    if(y + 1 == ColCnt)
                        break;
                    ++y;
                }
                ++x;
            }
        }
    }
}

小细节变量的命名自己要看清楚啊,我写的乱七八糟的但是运行没有问题,后续注意代码的简洁性

原文链接:QTableWidget实现复制粘贴_qtablewidget复制粘贴_Dxg_01的博客-CSDN博客

=================

QT tableWidget 复制到粘贴板

全部复制(不含标题):
void FormAssets_brow::setClipboard()
{
    int rows=ui->tableWidget1->rowCount();
    int column=ui->tableWidget1->columnCount();
    QString str="";
    for(int i=0; i<rows; i++) // 取出每个格子的内容
    {
        for(int j=0; j<column; j++){
            if(ui->tableWidget1->item(i,j) != NULL){//一定要先判断非空,否则会报错
                str.append(ui->tableWidget1->item(i,j)->text());
                str.append("\t");
            }else{
                str.append(""); //空字符弄成空格
                str.append("\t");
            }
        }
        str.append("\n");
    }
    QClipboard *board = QApplication::clipboard();
    board->setText(str);
    QMessageBox::information(NULL, "信息", "复制成功!");
}

str.append(""); //空字符弄成空格

在字符串中的“空字符”,应该还包含有“\t”“\n”之类的不可见控制字符?

在字符串中的“空格”,应该为“空格\t”“空格\n”,包含了不可见控制字符?

选中复制:
QList<QTableWidgetItem*> tableWidgetItem = ui->tableWidget->selectedItems();
  if(tableWidgetItem.count()==0) //如果没有选择,返回
     return;
    
//选择范围
int topRow ,buttomRow, leftColumn, rightColumn;
QList<QTableWidgetSelectionRange> tableSelectRange= ui->tableWidget->selectedRanges();
for(int i=0;i<tableSelectRange.count();i++)
{
    topRow= tableSelectRange.at(i).topRow();
    buttomRow=tableSelectRange.at(i).bottomRow();
    leftColumn=tableSelectRange.at(i).leftColumn();
    rightColumn=tableSelectRange.at(i).rightColumn();
}

//复制到cliptext
QString clipText;
for (int i=topRow;i<=buttomRow;i++) {
    for (int j=leftColumn;j<=rightColumn;j++) {
        QString text;
        if( ui->tableWidget->item(i,j)!=nullptr )//这个很重要
            text = ui->tableWidget->item(i,j)->text();
        clipText.append(text);
        clipText.append("\t");
    }
    clipText.chop(1);//删除末尾一个字符
    clipText.append("\n");
}

QClipboard *clipboard = QApplication::clipboard();//复制到剪贴板,可以粘贴到excel
clipboard->setText(clipText );

风帆小筑-QT tableWidget 复制到粘贴板

问题:bug

1. 和excel类似,框选内容复制,粘贴。

2. 框选包含了末列,功能ok。否则,有时ng。

这是转载别人的,并做了一些小bug的修改而已。

解决:解决!

一些很简单的应用,本文的源码、还是可用的。比如:一眼可以看出“框选拷贝/框选粘贴” 是否有错的场景,

文本输入:是直接在 Qt Ui中输入,不是从其他文件中拷贝而来;这样应该没有问题?

问题原因:估计是框选拷贝操作时,当在框选的单元格中,存在着某些会影响到这种操作的非显示控制符;如此,将这些产生问题的非显示的控制符也一起复制了,造成 bug。

比如:直接从网页,或者其他的什么地方的内容,通过粘贴板,复制到上述的表格中。

由于这类内容,可能包含了各种各样的不可见符号;因此,必须增加代码来对这些 特殊的、不可见的、转义的符号进行处理;然后,才能粘贴到上述的表格里。

可能解决:

1. 需要添加代码,对框选单元格中的非显示控制符进行清除;然后,再添加由用户控制的所需非显示控制符,如此解决?<< 除非找到现成的轮子,否则,自己造、还有跨平台,就是一件麻烦事了?还不如采用导入、导出方式,虽然步骤多了,但是简单。

2. 点 1所说的复制、粘贴功能,使用了操作系统的剪切板,如果不适用剪切板,应该就是可控的了。但此时只能在 QTableWidget内部进行复制、粘贴。

3. 使用导入、导出功能,应该可以将从网页中复制出来的表格,首先进行过滤吧?

4. 其他的解决方案?

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值