如何在Windows Qt 5中以编程方式处理交互式CLI [英] How to handle interactive CLI programmatically in Qt 5 for Windows

查看:371
本文介绍了如何在Windows Qt 5中以编程方式处理交互式CLI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下交互式CLI-

I have the following interactive CLI -

c:\TEST> python test.py    
Running test tool.    
$help    
   |'exec <testname>' or 'exec !<testnum>'    
   |0 BQ1    
   |1 BS1    
   |2 BA1    
   |3 BP1    
$exec !2    
   |||TEST BA1_ACTIVE    
$quit    
c:\TEST>

有人知道如何在Qt5中做到这一点。我尝试使用 QProcess ,但是由于用户定义了 exec!2 ,因此它无法处理上面显示的交互式命令行。

Does anyone know how to do this in Qt5. I try QProcess, but it does not handle the interactive command line shown above since the exec !2 is user defined.

例如, QProcess 可以处理 python test.py 如下所示,但是,我们如何处理CLI内部的命令,例如 exec!2

For example, QProcess can handle python test.py as shown in the following, however, how do we handle the command inside the CLI, such as exec !2

QProcess *usbProcess;
usbProcess = new QProcess();

QString s = "python test.py"; 
// ??? how do we handle interactive commands, 
// such as 'exec !2' or 'exec !1' and etc ???

usbProcess->start(s);
//usbProcess->waitForReadyRead();
//usbProcess->waitForFinished();
QString text =  usbProcess->readAll();
qDebug() << text;

以下仅是示例代码,而test.py必将保持不变!我只是想在test.py之外找到解决方案。

The following is just a sample code and the test.py shall be as it is! I am just trying to find a solution outside the test.py.

"""---beginning test.py---"""

from cmd import Cmd

class MyPrompt(Cmd):

def do_help(self, args):
    if len(args) == 0:
        name = "   |'exec <testname>' or 'exec !<testnum>'\n   |0 BQ1\n   |1 BS1\n   |2 BA1\n   |3 BP1'"
    else:
        name = args
    print ("%s" % name)

def do_exec(self, args):
    if (args == "!0"):
        print ("|||TEST BQ1_ACTIVE")
    elif (args == "!1"):
        print ("|||TEST BS1_ACTIVE")
    elif (args == "!2"):
        print ("|||TEST BA1_ACTIVE")
    elif (args == "!3"):
        print ("|||TEST BP3_ACTIVE")
    else:
        print ("invalid input")

def do_quit(self, args):
    print ("Quitting.")
    raise SystemExit

if __name__ == '__main__':
    prompt = MyPrompt()
    prompt.prompt = '$ '
    prompt.cmdloop('Running test tool.')
"""---end of test.py---"""


推荐答案

首先避免使用waitForXXX方法,而要使用Qt的主要优点:信号和插槽。

First avoid using the waitForXXX methods, use the main virtue of Qt: the signals and the slots.

对于 QProcess ,您必须使用 readyReadStandardError readyReadStandardOutput ,另一方面,程序不能为 python test.py ,程序为 python ,其参数为 test.py

In the case of QProcess you must use readyReadStandardError and readyReadStandardOutput, on the other hand the program can not be "python test.py", the program is "python" and its argument is "test.py".

以下示例为在Linux上进行了测试,但我认为您应该进行的更改是设置python可执行文件和.py文件的路径

The following example has been tested in Linux but I think the changes you should make is to set the paths of the python executable and the .py file

#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QProcess process;
    process.setProgram("/usr/bin/python");
    process.setArguments({"/home/eyllanesc/test.py"});

    // commands to execute consecutively.
    QList<QByteArray> commands = {"help", "exec !2", "exec !0", "help", "exec !1", "exec !3", "quit"};
    QListIterator<QByteArray> itr (commands);

    QObject::connect(&process, &QProcess::readyReadStandardError, [&process](){
        qDebug()<< process.readAllStandardError();
    });
    QObject::connect(&process, &QProcess::readyReadStandardOutput, [&process, &itr](){
        QString result = process.readAll();
        qDebug().noquote()<< "Result:\n" << result;
        if(itr.hasNext()){
            const QByteArray & command = itr.next();
            process.write(command+"\n");
            qDebug()<< "command: " << command;
        }
        else{
            // wait for the application to close.
            process.waitForFinished(-1);
            QCoreApplication::quit();
        }
    });

    process.start();

    return a.exec();
}

输出:

Result:
 Running test tool.
$ 
command:  "help"
Result:
    |'exec <testname>' or 'exec !<testnum>'
   |0 BQ1
   |1 BS1
   |2 BA1
   |3 BP1'
$ 
command:  "exec !2"
Result:
 |||TEST BA1_ACTIVE
$ 
command:  "exec !0"
Result:
 |||TEST BQ1_ACTIVE
$ 
command:  "help"
Result:
    |'exec <testname>' or 'exec !<testnum>'
   |0 BQ1
   |1 BS1
   |2 BA1
   |3 BP1'
$ 
command:  "exec !1"
Result:
 |||TEST BS1_ACTIVE
$ 
command:  "exec !3"
Result:
 |||TEST BP3_ACTIVE
$ 
command:  "quit"
Result:
 Quitting.

这篇关于如何在Windows Qt 5中以编程方式处理交互式CLI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆