1:ctrl+c, ctrl+v 实现方法,界面类重写keyPressEvent。 添加菜单m_tablewidgetMenu成员。
m_ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
auto buttonAction_right_copy = new QAction(tr(sm::GetCommonProcessIns().string_To_UTF8("复制(Ctrl_C)").c_str()), this);
auto buttonAction_right_pause = new QAction(tr(sm::GetCommonProcessIns().string_To_UTF8("粘贴(Ctrl_V)").c_str()), this);
m_tablewidgetMenu = new QMenu(m_ui->tableWidget);
m_tablewidgetMenu->addAction(buttonAction_right_copy);
m_tablewidgetMenu->addAction(buttonAction_right_pause);
setFocusPolicy(Qt::StrongFocus); // 必须设置widget可以拥有焦点(注意:默认的focusPolicy是NoFocus,这会导致无法捕获Ctrl/Alt/Shfit...之外的字符按键),捕获ctrl+c .ctrl+v;
// ==== 鼠标右键 文本复制 ====//
connect(buttonAction_right_copy, &QAction::triggered, [this]
{
RightCopySet();
});
// ==== 鼠标右键 文本粘贴 ====//
connect(buttonAction_right_pause, &QAction::triggered, [this]
{
RightPasteSet();
});
// ==== 表格鼠标右击打开菜单 ====//
connect(m_ui->tableWidget, &QTableWidget::customContextMenuRequested, [this](const QPoint& pos)
{
int num = m_ui->tableWidget->rowCount();
int h = m_ui->tableWidget->rowHeight(0);
if (pos.y() > h * num)
{
return;
}
m_tablewidgetMenu->exec(QCursor::pos());
});
void PCBPanelDialog::keyPressEvent(QKeyEvent* event)
{
if (event->matches(QKeySequence::Paste))
{
RightPasteSet();
}
else if (event->matches(QKeySequence::Copy)) {
RightCopySet();
}
return QWidget::keyPressEvent(event);
}
2:Qt tablewidget 表格选中复制, 将选择内容粘贴到剪切板,可以复制到excel中。
void PCBPanelDialog::RightCopySet()
{
QString copy_text;
// Qtablewidget选择的行列范围。
const auto& selectrange_list = m_ui->tableWidget->selectedRanges();
bool hor_sel = false;
bool ver_sel = false;
int flag_sel = 0;
// 如果ctrl多选,selectrange_list>=2 ,
for (const auto& select_range : selectrange_list) {
//跳着选且水平选 ,列选
if (flag_sel < selectrange_list.size() - 1) {
if (selectrange_list[flag_sel].leftColumn() == selectrange_list[flag_sel + 1].rightColumn())
hor_sel = true;
//跳着选且垂直选,行选
else if (selectrange_list[flag_sel].topRow() == selectrange_list[flag_sel + 1].bottomRow()) {
ver_sel = true;
}
}
for (int iRow = select_range.topRow(); iRow <= select_range.bottomRow(); ++iRow) {
QString tempItem;
for (int iCol = select_range.leftColumn(); iCol <= select_range.rightColumn(); ++iCol) {
QTableWidgetItem* p_item = m_ui->tableWidget->item(iRow, iCol);
if (p_item) {
tempItem.append(p_item->text());
// 行的最后一个一定加\n,倒数第二个\t。
if (iCol != select_range.rightColumn() || (ver_sel && flag_sel < selectrange_list.size() - 1))
tempItem.append('\t');
}
}
copy_text.append(tempItem);
if (select_range.rowCount() >= 1 || hor_sel)
copy_text.append('\n');
}
++flag_sel;
}
QApplication::clipboard()->setText(copy_text);
}
3:Qt tablewidget 表格选中粘贴, 将选择内容或者excel内容 粘贴到表格。
void PCBPanelDialog::RightPasteSet()
{
//获取剪切板内容
QClipboard* clip_board = QApplication::clipboard();
QString copy_content = clip_board->text();
//先判断能否使用" \n"分割,若不匹配则改为使用"\n"分割
QString regex1 = " \n";
QString regex2 = " \t";
if (copy_content.split(" \n").size() <= 1)
{
regex1 = "\n";
regex2 = "\t";
}
QStringList split_list = copy_content.split(regex1);
// 获取选中的行数和列数
int row = split_list.size() -1;
if (row == 0) {
OperationCheckDialog* operationcheck_dialog = new OperationCheckDialog(sm::WidgetType::Tip, "粘贴内容不符合要求,请重新复制文本文件!", 1, this);
operationcheck_dialog->exec();
return;
}
QStringList data_list;
for (int i = 0; i < split_list.size() - 1; i++)
{
data_list.append(split_list.at(i).split(regex2));
}
// 判断是否只有数字,非法数组return;
QRegExp regex("^-?\\d+(\\.\\d+)?$");
for (auto iter: data_list)
{
if (regex.exactMatch(iter)) {
continue;
}
else {
OperationCheckDialog* operationcheck_dialog = new OperationCheckDialog(sm::WidgetType::Tip, "粘贴内容不符合要求,请重新复制文本文件!", 1, this);
operationcheck_dialog->exec();
return;
}
}
int col = data_list.size() / row;
// 获取选中表格的行列索引
QTableWidgetItem* currentItem = m_ui->tableWidget->currentItem();
int select_row = 0;
int select_col = 0;
if (currentItem) {
select_row = currentItem->row();
select_col = currentItem->column();
// 如果选中的列为标题项,提示
if (select_col == 0) {
OperationCheckDialog* operationcheck_dialog = new OperationCheckDialog(sm::WidgetType::Tip, "表头项不可复制,请选择X,Y,R项粘贴!", 1, this);
operationcheck_dialog->exec();
return;
}
// 如果选中的列+粘贴的列大于表格的列数。
// 这里可以按需求修改,主要看表格是不是都显示数字。
if (select_col + col - 1 > 3) {
OperationCheckDialog* operationcheck_dialog = new OperationCheckDialog(sm::WidgetType::Tip, "文本粘贴的列数大于表格的列数,请重新复制!", 1, this);
operationcheck_dialog->exec();
return;
}
// 如果选中的行+粘贴的行大于表格的行数
if (select_row + row - 1 > m_ui->tableWidget->rowCount()-1) {
OperationCheckDialog* operationcheck_dialog = new OperationCheckDialog(sm::WidgetType::Tip, "文本粘贴的行数大于表格的行数,请重新复制,或增加表格行数!", 1, this);
operationcheck_dialog->exec();
return;
}
}
else {
OperationCheckDialog* operationcheck_dialog = new OperationCheckDialog(sm::WidgetType::Tip, "请选择要复制的起始表格!", 1, this);
operationcheck_dialog->exec();
return;
}
// 填充表格,
int list_index = 0;
int row_total = select_row + row;
int col_total = select_col + col;
for (int item_row = select_row; item_row < row_total; item_row++)
{
for (int item_col = select_col; item_col < col_total; item_col++)
{
FillItemData(item_row, item_col, data_list[list_index++]);
}
}
}