Qt tablewidget 复制,粘贴,快捷键设置(ctrl+c,ctrl+v)

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++]);
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值