张裕 发表于 2026-2-11 15:14:08

【QT常用技能解说】tableWidget右键菜单及多历程编程

前言

        本文在QT项目标开发框架的根本上(源代码)增长tableWidget的右键菜单功能,并使用历程实现ping盘算机的功能来解说,本文不对历程间通讯举行解说。
概述

        一个项目在开发过程中,通常面对着引入“第三方应用”,有些应用提供了源代码、动态库,这些是可以平滑的“嵌入”到项目代码中(比如框架里的xml处置处罚等),但有些是固化的应用,比如背景下令行的ping等,在QT项目必要时,启动一个新历程实行下令并获取返回效果即可到达项目目标,框架内里特意提供了tools目次,目标就是用于存放“第三方”可用的工具。
应用效果图

https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pLWJsb2cuY3NkbmltZy5jbi9kaXJlY3QvNGVjMjcwMzIzZGI2NGY5Njk5MTE3NjMyZDgxOTE5MjAucG5n
图1 tableWidget的右键菜单功能--ping此盘算机
https://dis.qidao123.com/imgproxy/aHR0cHM6Ly9pLWJsb2cuY3NkbmltZy5jbi9kaXJlY3QvYzM3NzVjZDI4ZjBiNGQzOWEyMzdjZWRmNDEwZTYyYTYucG5n
图2 ping对话框(创建新历程实行背景ping下令并获取返回效果)
功能解说

1、tableWidget添加右键菜单功能

起首提供setContextMenuPolicy设置右键功能,在tab_basemsg.cpp中增长以下代码:
ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);//设置右键菜单功能 接下来必要在tab_basemsg.h中添加槽函数,分成两种环境:
private slots:

    //处理右键菜单请求
    void on_tableWidget_customContextMenuRequested(const QPoint &pos);//此为系统默认响应槽函数
    void tableWidget_MenuRequested(const QPoint &pos);//需要通过connect指向 (1)如果声明on_tableWidget_customContextMenuRequested(const QPoint &pos);体系默认绑定了右键菜单功能,不必要connect来关联信号和槽;
(2)如果声明中不带on_tableWidget_,比如声明tableWidget_MenuRequested(const QPoint &pos);时,必须使用connect来关联信号和槽,为了代码管理规范,浅易用此种方式。
此时在tab_basemsg.cpp中增长connect毗连信号和槽函数:
ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);//设置右键菜单功能connect(ui->tableWidget, &QTableWidget::customContextMenuRequested, this, &tab_basemsg::tableWidget_MenuRequested); 在tab_basemsg.cpp中槽函数代码如下:
void tab_basemsg::tableWidget_MenuRequested(const QPoint &pos) {
    QModelIndex index = ui->tableWidget->indexAt(pos);
    if (!index.isValid()) return;

    QMenu menu(this);
    QAction *DiplaymsgAction = menu.addAction(tr("查看详情"));
    connect(DiplaymsgAction,&QAction::triggered,[=](){
      //获取选择的单元格
      QList<QTableWidgetItem *> selected_cells = ui->tableWidget->selectedItems();
      if(!selected_cells.isEmpty()){
            QTableWidgetItem *codeCell = ui->tableWidget->item(selected_cells.first()->row(),HEAD_BASEMSG_CODE);
            if(codeCell!=nullptr){
                QString code = codeCell->text();
                stBasemsg basemsg=m_basemsgmap;
                basemsgDialg->setModal(false);
                basemsgDialg->setWindowTitle("保存");
                //basemsgDialg->setFixedSize(500,400);
                basemsgDialg->open();
                basemsgDialg->init(1,basemsg);
                basemsgDialg->exec();
            }
      }
    });
    QAction *NetpingAction = menu.addAction(tr("Ping此计算机"));
    connect(NetpingAction,&QAction::triggered,[=](){
      //获取选择的单元格
      QList<QTableWidgetItem *> selected_cells = ui->tableWidget->selectedItems();
      if(!selected_cells.isEmpty()){
            QTableWidgetItem *codeCell = ui->tableWidget->item(selected_cells.first()->row(),HEAD_BASEMSG_CODE);
            if(codeCell!=nullptr){
                QString code = codeCell->text();
                stBasemsg basemsg=m_basemsgmap;
                QString ip=basemsg.Ip;
                qDebug() << __LINE__ << ip;
                pingdlg->setIp(ip);
                pingdlg->setModal(false);
                pingdlg->setWindowTitle("PING测试");
                pingdlg->setFixedSize(500,400);
                pingdlg->open();
                pingdlg->init();
                pingdlg->exec();
            }
      }
    });

    menu.exec(QCursor::pos());
    //menu.exec(ui->tableWidget->mapToGlobal(pos));
} 详细的右键菜单功能是在槽函数中增长的,增长的方式如下:
QMenu menu(this);
QAction *DiplaymsgAction = menu.addAction(tr("查看详情"));
connect(DiplaymsgAction,&QAction::triggered,[=](){});
QAction *NetpingAction = menu.addAction(tr("Ping此计算机"));
connect(NetpingAction,&QAction::triggered,[=](){}); 2、多历程调用背景下令

通过QProcess process;(头文件#include <QProcess>)调用新历程来实行背景下令,并获取返回值输出到文本框中,如下代码所示
#include <QTextCodec>
#include <QProcess>
void pingDialog::on_start_clicked()
{
    ui->textBrowser->setReadOnly(false);//
    ui->textBrowser->setText("--------ping start--------");
    QString times = ui->timeBox->currentText();
    QString Ipstr=ui->ipEdit->text();
    QString cmd = QString("ping -n %1 %2").arg(times).arg(Ipstr);//组装命令

    m_isStart=true;
    QProcess process;//创建新进程
    process.start(cmd);//通过新进程执行后台命令
    if(process.waitForFinished()){//等待进程返回后获取输出内容
      // 读取进程的输出
      QString output = QString::fromLocal8Bit(process.readAllStandardOutput());
      QTextCodec *codec = QTextCodec::codecForName("GBK");
      QString unicodeOutput = codec->toUnicode(output.toLocal8Bit());
      ui->textBrowser->append(unicodeOutput);
    }
} 注意事项

直接使用QProcess实行背景下令时,在下令实行过程中(比如把ping的次数调为10次),QT应用是卡死的,用鼠标根本拉不动,缘故因由是调用历程实行背景下令时,对于QT来说是壅闭方式!!要等历程输出内容返回后才规复,这种在体验上很不友好,下一篇【QT常用技能解说】多线程编程处置处罚卡顿将引入多线程来办理此类壅闭题目。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
页: [1]
查看完整版本: 【QT常用技能解说】tableWidget右键菜单及多历程编程