The best solution here is using the argparse
module's parse_known_args()
method (docs) to process the non-Qt command line options first. It's no more work in configuring the ArgumentParser
—it just changes which method you call, and gives you a tuple instead of a single object in the return. That gives you the best of both worlds.
A simplified example that catches only a couple of the Qt 4.8 arguments and a few others, but gives the general idea.
# my_script.pyimport argparsefrom PyQt4 import QtGui # this will work with PySide.QtGui, toodef process_cl_args(): parser = argparse.ArgumentParser() parser.add_argument('-s', '--swallow', action='store') # optional flag parser.add_argument('holy_hand_grenade', action='store') # positional argument parsed_args, unparsed_args = parser.parse_known_args() return parsed_args, unparsed_argsif __name__ == '__main__': parsed_args, unparsed_args = process_cl_args() # QApplication expects the first argument to be the program name. qt_args = sys.argv[:1] + unparsed_args app = QtGui.QApplication(qt_args) # ... the rest of your handling: `sys.exit(app.exec_())`, etc.
Assume you were to run this like so:
$ python my_script.py -dograb --swallow=unladen 3 -style cde
Then parsed_args
would have the usual Namespace
with holy_hand_grenade
set to 3
and --swallow
set to 'unladen'
, while unparsed_args
would have a simple list: ['-dograb', '-style,''cde']
. This in turn can be passed normally to the QApplication
with the inclusion of the program name from sys.argv[0]
(thanks to marcin for pointing this out). We use sys.argv[:1]
to get an array for concatenation with unparsed_args
; you could just as well do [sys.argv[0]]
Among other things, this lets you set up your application to specify whether to launch the Qt UI, to run as a command line, to run unit tests, and so forth instead if you so desired. Handling the non-Qt (or anything else) arguments first is better because it does not leave argparse
dependent on the setup you're using, but the other way around.