QTableWidget单元格的内容:
主要实现单个单元格、整行、整列、多个单元格的复制粘贴
对于文本内容
主要实现内容与样式的复制粘贴
对于公式、日期、数字
实现内容递增、样式的复制粘贴
粘贴前
粘贴后
粘贴前
粘贴后
#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);;
}
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";
}
文本内容效果展示