Qt通过QProcess启动进程并传递命令行参数

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Qt通过QProcess启动进程并传递命令行参数

QProcess

用于完成启动外部程序,并与其交互通信。

启动外部程序的两种方式

依赖式

外部程序启动后,将随主程序的退出而退出。

void start(const QString & program,const QStringList &arguments,OpenMode mode = ReadWrite)


分离式:

外部程序启动后,当主程序退出时并不退出,而是继续运行。

void startDetached(const QString & program,const QStringList & arguments,const QString&workingDirectory=QString(),qint64 *pid =0)

启动进程前的预处理

设置启动路径

可以提前设置启动路径,也可以在start方法中进行设置。

void setProgram(const QString & program)

设置启动命令参数

可以提前设置启动命令参数也可以不设置(非必须),也可以在start方法中进行设置。

void setArguments(const QStringList & arguments)
• 1

启动的状态

1、外部程序未启动时,状态是NotRunning;

2、外部程序启动时,状态是Starting;

3、外部程序启动之后,状态是Running,并发出started()信号,此时可对QProcess进行RW操作;

4、外部程序退出时,状态是NotRunning,并发出finished()信号。finished()信号会包含退出码和退出状态信息,可通过exitCode()和exitStatus()来获得。

5、外部程序发生错误时,Qprocess会发出一个error()信号,可通过error()来获得其错误类型,通过state()获得当前程序的状态。


更多说明

有更多想了解Qprocess类的信息,可阅读Qt 助手。 下面列出了,所有可调用的方法。

Public Functions

 QProcess(QObject *parent = nullptr)
 virtual ~QProcess()
 QStringList arguments() const
 std::function<void ()> childProcessModifier() const
 void closeReadChannel(QProcess::ProcessChannel channel)
 void closeWriteChannel()
 QProcess::CreateProcessArgumentModifier createProcessArgumentsModifier() const
 QProcess::ProcessError error() const
 int exitCode() const
 QProcess::ExitStatus exitStatus() const
 QProcess::InputChannelMode inputChannelMode() const
 QString nativeArguments() const
 QProcess::ProcessChannelMode processChannelMode() const
 QProcessEnvironment processEnvironment() const
 qint64 processId() const
 QString program() const
 QByteArray readAllStandardError()
 QByteArray readAllStandardOutput()
 QProcess::ProcessChannel readChannel() const
 void setArguments(const QStringList &arguments)
 void setChildProcessModifier(const std::function<void ()> &modifier)
 void setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier modifier)
 void setInputChannelMode(QProcess::InputChannelMode mode)
 void setNativeArguments(const QString &arguments)
 void setProcessChannelMode(QProcess::ProcessChannelMode mode)
 void setProcessEnvironment(const QProcessEnvironment &environment)
 void setProgram(const QString &program)
 void setReadChannel(QProcess::ProcessChannel channel)
 void setStandardErrorFile(const QString &fileName, QIODeviceBase::OpenMode mode = Truncate)
 void setStandardInputFile(const QString &fileName)
 void setStandardOutputFile(const QString &fileName, QIODeviceBase::OpenMode mode = Truncate)
 void setStandardOutputProcess(QProcess *destination)
 void setWorkingDirectory(const QString &dir)
 void start(const QString &program, const QStringList &arguments = {}, QIODeviceBase::OpenMode mode = ReadWrite)
 void start(QIODeviceBase::OpenMode mode = ReadWrite)
 void startCommand(const QString &command, QIODeviceBase::OpenMode mode = ReadWrite)
 bool startDetached(qint64 *pid = nullptr)
 QProcess::ProcessState state() const
 bool waitForFinished(int msecs = 30000)
 bool waitForStarted(int msecs = 30000)
 QString workingDirectory() const


Signals

 void errorOccurred(QProcess::ProcessError error)
 void finished(int exitCode, QProcess::ExitStatus exitStatus = NormalExit)
 void readyReadStandardError()
 void readyReadStandardOutput()
 void started()
 void stateChanged(QProcess::ProcessState newState)


设计一个拉起进程的程序

基本设计思路

1、点击【选择应用】按钮,即可打开文件资源管理器。选择需要拉起的应用,即可在后面的label中显示绝对路径。然后在【添加命令行参数】区域下方添加已注册好的命令以及期望值(这个命令行参数将会在后面介绍)。

2、然后点击右上区域的【拉起进程】按钮,然后会在【日志输出】区域输出拉起成功与否的日志说明和PID号等。最后可以通过【杀死进程】来结束该进程。


效果图

核心代码

控件对象

【添加命令行参数】区域的控件对象为:textEdit

【日志输出】区域的控件对象为:textEdit_2

【选择应用】按钮的控件对象为:pushButton

【拉起进程】按钮的控件对象为:pushButton_3

【杀死进程】按钮的控件对象为:pushButton_2


header file(头文件)

#include <QFileDialog>
#include <QProcess>


member variable(成员变量)

QProcess* m_Process;


【选择应用】按钮的槽函数

void MainWindow::on_pushButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,"选择应用程序","./","Txt files(*.exe)");
    ui->lineEdit->setText(fileName);
}


【拉起进程】按钮的槽函数

void MainWindow::on_pushButton_3_clicked()
{
    if(nullptr != m_Process)
    {
        m_Process->close();
        delete m_Process;
        m_Process = nullptr;
        ui->textEdit_2->append(QString("杀死已存在的进程!"));
    }
    m_Process = new QProcess(this);
    QString fileName = ui->lineEdit->text();
    QStringList args = ui->textEdit->toPlainText().split("\n");
    m_Process->start(fileName, args);
    if(m_Process->waitForStarted(3000))
    {
        qint64 PID =m_Process->processId();
        ui->textEdit_2->append(QString("进程拉起成功!PID = %1").arg(PID));
    }
    else
    {
        ui->textEdit_2->append(QString("error:进程拉起失败!"));
    }
}


【杀死进程】按钮的槽函数

void MainWindow::on_pushButton_2_clicked()
{
    if(nullptr != m_Process)
    {
        m_Process->close();
        ui->textEdit_2->append(QString("进程杀死成功!"));
    }
}


UI布局

组织架构

测试效果


Qt解析命令行参数

Qt可以通过QCommandLineParserQCommandLineOption类可以对命令行进行解析。

命令说明

 * 单字符的命令通常以“-” 开头:-h
 * 多字符的命令通常以“--”开头:--help
 * 注意 :通常情况下 -abc 会被等同于 -a;-b;-c
 * 命令后面还可以附带值 例如 -h=45454


增加命令

    QCommandLineParser parser;
    /*
     *对于有期望值的命令 需要设置Value(setValue) 否则会报错
     */
    QList<QCommandLineOption> ops;
    // 带有期望值的open命令
    QCommandLineOption op("open");
    op.setValueName("string");
    // 带有期望值的h命令
    QCommandLineOption op2("h");
    op2.setValueName("double");
    /*
     *  这里需要添加所有的命令  类似于注册效果
     */
    ops << op << op2;
    parser.addOptions(ops);
    // 处理用户给出的实际命令
    parser.process(a);


解析命令

    // 解析注册过的命令
    if(parser.isSet(op))
    {
        parser.value(op);
    }


设计一个后台进程的程序

组织架构

核心代码

#include <QCoreApplication>
#include <QCommandLineParser>
#include <QFile>
#include <string>
#include <QDebug>
#include <iostream>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    /*
     * 单字符的命令通常以“-” 开头:-h
     * 多字符的命令通常以“--”开头:--help
     *
     * 注意 :通常情况下 -abc 会被等同于 -a;-b;-c
     */
    QCommandLineParser parser;
    /*
     *对于有期望值的命令 需要设置Value(setValue) 否则会报错
     */
    QList<QCommandLineOption> ops;
    // 带有期望值的open命令
    QCommandLineOption op("open");
    op.setValueName("string");
    // 带有期望值的h命令
    QCommandLineOption op2("h");
    op2.setValueName("double");
    /*
     *  这里需要添加所有的命令  类似于注册效果
     */
    ops << op << op2;
    parser.addOptions(ops);
    // 处理用户给出的实际命令
    parser.process(a);
    QFile file("e://1.txt");
    file.open(QIODevice::Append);
    if(!file.isOpen())
    {
        exit(EXIT_FAILURE);
    }
    // 解析注册过的命令
    if(parser.isSet(op))
    {
        std::string log = "open:" + parser.value(op).toStdString() + "\n";
        file.write(log.c_str());
        std::cout << log;//<< std::endl;
    }
    if(parser.isSet(op2))
    {
        std::string log = "h:" + parser.value(op2).toStdString() + "\n";
        file.write(log.c_str());
        std::cout << log;//<< std::endl;
    }
    file.close();
    return a.exec();
}


通过Cmd进行测试命令行参数

文件输出


后续

这时其实还不能完整调用,因为部分环境还没有。所以还需要对这个程序进行打包发布。后续将会介绍Qt自带的打包工具。本文内容太多了,就下一篇文中介绍吧。

目录
相关文章
|
6月前
|
编译器 C++ 开发者
QT基础【7-跨进程发送信号】
QT基础【7-跨进程发送信号】
|
6月前
QT自定义信号,信号emit,信号参数注册
使用signals声明返回值是void在需要发送信号的地方使用emit 信号名字(参数)进行发送在需要链接的地方使用connect进行链接ct进行链接。
67 0
QT自定义信号,信号emit,信号参数注册
|
测试技术
QT --- VS2017+Qt5.12 编译报错【E2512 功能测试宏的参数必须是简单标识符 】的解决方法
QT --- VS2017+Qt5.12 编译报错【E2512 功能测试宏的参数必须是简单标识符 】的解决方法
513 0
|
Windows
windows windows10 查看进程的命令行
windows windows10 查看进程的命令行
70 0
|
5月前
|
Linux 调度
Linux进程——Linux进程间切换与命令行参数
Linux进程——Linux进程间切换与命令行参数
49 1
|
5月前
|
计算机视觉 Python
Python 多进程以及进程共享参数
这段时间在做一款游戏的挂机软件,我发现进入游戏后的逻辑和判断人物死亡的逻辑需要同时进行(因为不知道什么时候就暴毙了),以前我习惯用线程来进行同步,但是我发现由于我的代码中的逻辑比较复杂,且有多个嵌套的无限循环会导致线程阻塞,所以我决定用进程的方式来实现同步运行。
|
5月前
|
监控 Linux iOS开发
经验大分享:Qt之QProcess
经验大分享:Qt之QProcess
132 0
|
6月前
|
监控 Linux 开发者
【专栏】在Linux系统管理中,终止不响应或资源消耗大的进程至关重要
【4月更文挑战第28天】在Linux系统管理中,终止不响应或资源消耗大的进程至关重要。本文介绍了如何查找、终止和监控进程。使用`ps`和`grep`组合查找特定进程,或通过`pgrep`获取PID。使用`kill`命令(默认发送TERM信号)终止进程,如需强制终止,可使用`kill -9`发送`SIGKILL`信号。监控进程可借助`ps`、`top`、`htop`及`watch`命令。理解这些技能将有助于更有效地管理Linux进程。
125 3
|
SQL 数据库 数据库管理
Qt操作Sqlite类封装,及命令行导入csv文件到Sqlite数据库
Qt操作Sqlite类封装,及命令行导入csv文件到Sqlite数据库
|
6月前
|
API
QT中使用 WinExec API 参数不支持中文路径的解决办法
在QT中使用WinExec时,发现如果调用外部程序,如果路径或者参数含有中文路径,可能导致无法打开应用程序或者无法使用参数,解决办法,下面是简单的解决办法
201 0