PDA

View Full Version : QCommandLineParser to complex application



atomic
27th August 2014, 11:10
Hi,

I have question about QCommandLineParser
I read documentation about this class and I don't see support to several arguments with independent options,
for example in my app I need independent function to filesystem such as

# move [source] [destination] [options]
# move C:/first.txt D:/first.txt --information

# find [filename] [options]
# find somefile --type=txt --casesensitive=true --recursive=true

and many many more functions to filesystem and network.

But QCommandLineParser allow use option only for first argument so if my app name "test.exe" I
can only write such as

test.exe --[options] [optionalargument]

Maybe someone with you know how I can solve this problem?
My app must works similar a bash shell that is to say it must work in loop and operate with many classes,
many functions and many arguments with options.

Regards,

wysota
27th August 2014, 14:17
QCommandLineParser accepts a list of strings to use as arguments so you can preprocess the list manually and reorder or cut away some entries before passing the list to QCommandLineParser.

anda_skoa
27th August 2014, 15:17
The example given in the documentation does exactly what our "move" example does.

Cheers,
_

atomic
27th August 2014, 17:51
Please look for images.

1059310594

First problem - how adapt "Usage: " information to display only name of application / its alias not full path to program.

And when I write
# find --help

"Usage:" information should looks as
# Usage: LockCommand find [options]

How i can change "Usage:" information?

wysota
28th August 2014, 08:09
How i can change "Usage:" information?

Maybe you should write your own commandline parser? Apparently QCommandLineParser is not for you, it is suited for standard UNIX syntax cases where options come before positional arguments. Your case is obviously different.

anda_skoa
28th August 2014, 10:31
Apparently QCommandLineParser is not for you, it is suited for standard UNIX syntax cases where options come before positional arguments.

Options can be after positional arguments.
I wasn't sure either, so I copied the example from the documentation (the "copy program" one) and tried it myself.
It is possible to specify the -p option anywhere, before the two positional arguments, in between or after.

Cheers,
_

wysota
28th August 2014, 10:40
Options can be after positional arguments.
I wasn't sure either, so I copied the example from the documentation (the "copy program" one) and tried it myself.
It is possible to specify the -p option anywhere, before the two positional arguments, in between or after.


Ok, but I guess OP wants a specific order of arguments, e.g. with how find works: find <where> -what. You cannot change the order of arguments there for a number of reasons (I mean with this specific tool).

anda_skoa
28th August 2014, 12:03
I don't know, at least that is not what the first posting said.

It falsely claimed that options had to be passed first, which is not true.

Cheers,
_

wysota
28th August 2014, 13:05
I don't know, at least that is not what the first posting said.

It falsely claimed that options had to be passed first, which is not true.

Yes, I know. People don't always say what they really wanted to say ;)

atomic
29th August 2014, 12:32
"It falsely claimed that options had to be passed first, which is not true." - You have right. I am noob and
I mislead.

I solve my problem with the order arguments and options. Also solve problem with "Usage: " information
by write my own help function.

I have last question about this post.
I started with this code

.h


#ifndef COMMANDLINEMANAGER_H
#define COMMANDLINEMANAGER_H

#include <QObject>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QTextStream>
#include <QString>

#include <QDebug>


class CommandLineManager : public QObject
{
Q_OBJECT
public:
explicit CommandLineManager(QObject *parent = 0);

public slots:
void readInput();

private:


};

#endif // COMMANDLINEMANAGER_H


.cpp


#include "commandlinemanager.h"

CommandLineManager::CommandLineManager(QObject *parent) :
QObject(parent)
{
}

void CommandLineManager::readInput()
{
while( 1 ) {

QTextStream( stdout )<< "LockCommand" <<endl;
QTextStream( stdout )<< "# ";

QTextStream qin( stdin );
QStringList cmd = QCoreApplication::arguments()<< qin.readLine().split( " " );

QCommandLineParser parser;
parser.addHelpOption();
parser.addPositionalArgument("command", "The command to execute." );

parser.parse( cmd );

const QStringList args = parser.positionalArguments();
const QString command = args.isEmpty() ? QString() : args.first();
if (command == "open") {

// best way to do this function?
// emit open( arguments and options ); ?
}
if( command == "copy" ) {
// check next option
}

}
}


main


int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

QCoreApplication::setApplicationName( "LockCommand" );
QCoreApplication::setApplicationVersion( "1.0" );

CommandLineManager commandLineManager;
QMetaObject::invokeMethod( &commandLineManager, "readInput", Qt::QueuedConnection );

return a.exec();
}


I must use invokeMethod otherwise my readInput() function never allow to call app.exe().
Well I started?

And please tell me what is the best way to managment calls specific class /methods
for example when i read "open" with some arguments and options

I can connect in constructor with MyFileSystem class and then emit signal
if (command == "open") {
// best way to do this function?
// emit open( arguments and options ); ?
}

but if I will have np 50 functions I will have 50 if statement - it is good project?
Regards,

anda_skoa
29th August 2014, 13:26
This looks more like an approach for a factory to me.

You have a QCommandlineParser parse the initial commandline and extract the command name from the first positional argument, maybe handle any options that are not command specific if you have any.

Then you take the command and hand it to a factory class which instantiates a handler for that command.
This command handler can then use its own QCommandlineParser to parse the command specific arguments, even provide command specific help.

Cheers,
_