【QT常用技术讲解】tableWidget右键菜单及多进程编程

前言

本文在QT项目的开发框架的基础上(源代码)增加tableWidget的右键菜单功能,并使用进程实现ping计算机的功能来讲解,本文不对进程间通信进行讲解。

概述

一个项目在开发过程中,通常面临着引入"第三方应用",有些应用提供了源代码、动态库,这些是可以平滑的"嵌入"到项目代码中(比如框架里的xml处理等),但有些是固化的应用,比如后台命令行的ping等,在QT项目需要时,启动一个新进程执行命令并获取返回结果即可达到项目目的,框架里面特意提供了tools目录,目的就是用于存放"第三方"可用的工具。

应用效果图

图1 tableWidget的右键菜单功能--ping此计算机

图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[code];
                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[code];
                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常用技术讲解】多线程编程处理卡顿将引入多线程来解决此类阻塞问题。

相关推荐
Am心若依旧40925 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
明月看潮生27 分钟前
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
开发语言·青少年编程·单元测试·编程与数学·goweb
大G哥37 分钟前
java提高正则处理效率
java·开发语言
VBA63371 小时前
VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL
开发语言
轩辰~1 小时前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
小_太_阳1 小时前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it1 小时前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
古希腊掌管学习的神2 小时前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师2 小时前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
就爱学编程2 小时前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法