0

Qt5 provides two functions to process command line arguments in QCommandLineParser class. The signatures are:

  • process(const QStringList &arguments)
  • process(const QCoreApplication &app)

This works fine in C++ but Python has no overloading feature nor signature detection. Apparently,

 from PyQt5.QtCore import QCommandLineParser as qlp
 qlp.process(("myapp", "-opt", "file"))

(example oversimplified to make the point)

references the process(const QCoreApplication &app) variant and errors out because the argument in no QCoreApplication instance.

At this step, I don't want to instantiate some kind of application object because I don't know yet if I'll run a QCoreApplication or a QGuiApplication, which is determined by parsing the arguments.

How can I force the desired variant?

Alternately, how can I preparse the command line arguments to check if I need a GUI or not? (But this alternative may need as much work as parsing the arguments with QCommandLineParser)

ajlittoz
  • 414
  • 1
  • 5
  • 14
  • 1
    What's wrong with the standard [argparse](https://docs.python.org/3/library/argparse.html) module? Or even just checking the `sys.argv`. – musicamante Mar 12 '22 at 11:53
  • @musicamante: nothing wrong, but app will end up with Qt. `QCommandLineParser` nicely handles "usage", `--help` and `--version`. In addition, instead of having a huge help message, it is split into chunks associated with each option, resulting in a more easily maintenable source (at least more consistent when modifications are made to options). – ajlittoz Mar 12 '22 at 14:43
  • musicamante: make your comment an answer and I'll mark it. I think my question has no solution with PyQt5. I'll change my workflow to switch to `argparse` – ajlittoz Mar 12 '22 at 16:11
  • I just tried `process()` with your example and it works, as long as the given options exist (in your case `-opt` are considered shorthands for options `o`, `p` and `t`), otherwise it just calls `exit()` as explained in the documentation. Your *specific* code above won't work because `qlp` is the class, not a QCommandLineParser` instance, but if you actually created an instance, it shouldn't give you that error. – musicamante Mar 12 '22 at 18:29
  • Apologies, I oversimplified the example. I called `process` from an instance. Meanwhile, I experimented with `argparse`. My problem is with the options added by the desktop manager, i.e. all Qt or GTK configuration options. They are seen as unknown options by argparse. If I go through `QCommandLineParser()`, they are absorbed by the Qt library but this will probably initialize many unwanted "objects" in case I decide for a no-GUI processing. – ajlittoz Mar 13 '22 at 15:08
  • I don't see how to tackle the issue without parsing twice the command line: once to check for GUI/non-GUI, ignoring unknown options, and second for real, emitting errors for unknown options, supposing Qt ones have been removed by the library. – ajlittoz Mar 13 '22 at 15:15
  • Both argparse and QCommandLineParser provide ways to ignore unspecified arguments. That said, I'm not aware of "injected" options from the DM: that seems just wrong, as the DM shouldn't try to indiscriminately add arguments on its own, especially considering that if you're running the script with the specified interpreter (the `#!/usr/bin/...` header) it couldn't even know what to do - nor it should. What DM are you using? And what arguments are those? – musicamante Mar 14 '22 at 01:48
  • I am under KDE Plasma where you can customize window behaviour (e.g. define a default size, lock on a designated screen, …) application per application. This is forwarded to the widget library through additional options. Of course, this holds only for apps launched "graphically" (double-click on an icon or selection from app menu). When you launch from the terminal, nothing is added to the command. – ajlittoz Mar 14 '22 at 12:50
  • The problem with `parse_known_args(…)` is that I lose the ability to detect unknown options (typo error or completely unknown) because of the "transparency" towards library options and I probably face potential parsing errors when library options have a parameter. – ajlittoz Mar 14 '22 at 12:56
  • AFAIK, those options should be environmental variables, and it seems strange that Plasma adds arbitrary arguments (but I've not used Plasma in years). In any case, you could just use [`parse()`](https://doc.qt.io/qt-5/qcommandlineparser.html#parse) with the current arguments and then call [`unknownOptionNames()`](https://doc.qt.io/qt-5/qcommandlineparser.html#unknownOptionNames) to get a list of unrecognized options. – musicamante Mar 15 '22 at 19:30
  • In fact I don't know how to address the issue. I'm converting a 10+ y.o. program where the options are listed so that they aren't considered errors but not handled. Since there is also "modal" uses of options (some options may add details on the previous argument), stateful analysis of options is required. I'm looking at Action class for this. Anyway the generic Qt/GTK options problem remains. – ajlittoz Mar 17 '22 at 19:47
  • I'm curious. What options are added to the command line? And how did you set those configurations? – musicamante Mar 18 '22 at 01:27
  • To be honest, I never met these options insofar. They are declared in the old code. They correspond to generic Qt/GTK+ library options. I guess user may add them but I remember that in X Window era, X added many options on its own to the command line. So I fancied this was the same with modern windowing systems. I don't know what would happen if I remove them (probably an error if they're present). And I can't ask original authors because they've been out of the way for very long. I think the best path would be to completely reconsider the options and also eliminate the stateful aspect. – ajlittoz Mar 18 '22 at 08:34
  • So, you actually do *not* have overridden arguments added by the DM? Then, it's like I thought, the problem is solved, as there's no need to worry about something that won't happen in any reasonably modern system. – musicamante Mar 18 '22 at 11:44
  • I don't think it is solved. If a power user adds a library option which is not described in argparse, it will be rejected as faulty. The problem comes from the fact that this app can be run GUI and non-GUI. It is decided based on combination of options. This means that GUI library init is called after command line analysis and its specific arguments are still there in argparse. And I don't want to enumerate them because the library may evolve. – ajlittoz Mar 19 '22 at 09:32

0 Answers0