I'm still a beginner when it comes to programming, and I'm especially new when it comes GUI programming. I'm using python with PyQt4 and im following a tutorial guide. The following code block is relatively easy to follow:
import sys
from PyQt4 import QtGui
def window():
app = QtGui.QApplication(sys.argv)
w = QtGui.QWidget()
b= QtGui.QLabel(w)
b.setText("Hello World!")
w.setGeometry(100,100,200,50)
b.move(50,20)
w.setWindowTitle(“PyQt”)
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
window()
I can follow whats going on here quite well, but could someone explain to me what the sys.argv is actually doing? I don't want to just blindly put this in every time in the hope that it will make my code work!
The argc
(argument count = number of arguments) and argv
(an array, or list of argument values, depending on the language) is what the operating system gives to the program as parameters. In other worlds: "how it was called".
As clearly stated by cptPH's answer, this is not specific to Qt
or Python
. Have a look here:
https://en.wikipedia.org/wiki/Entry_point
For C and C++:
https://en.wikipedia.org/wiki/Entry_point#C_and_C.2B.2B
For Python:
https://en.wikipedia.org/wiki/Entry_point#Python
Even shell scripting have these, called "Positional parameters":
http://www.tldp.org/LDP/abs/html/othertypesv.html
Even if your program takes no command line options at all, whatever the language or OS (unless very, very exotic ones), you will always have to a bare minimum:
- a
argc
of 1, because,
argv
number 0 will be the name under which your program is called
(this may vary, for example if you call it via a symlink, or
simply because you changed the target binary of the build process,
and your program "foo" is now "bar" - ex use: don't use hardcoded program name when printing output, rather use argv
number 0).
Sooner or later, you'll be writing programs which use options/parameters. So you'll use these. Example: you may want to add a "--verbose" or "--debug" option. Or a "--input-file" if it's about file processing. Whatever. Your program will parse these argv at startup, and through your wise coding, will change its runtime behavior accordingly.
Example: even the Python can takes quite of lot of optional options, and processes them using argc
/argv
. From Python 3 man page:
python [ -B ] [ -b ] [ -d ] [ -E ] [ -h ] [ -i ] [ -I ]
[ -m module-name ] [ -q ] [ -O ] [ -OO ] [ -s ] [ -S ] [ -u ]
[ -v ] [ -V ] [ -W argument ] [ -x ] [ [ -X option ] -? ]
[ -c command | script | - ] [ arguments ]
...these are all possible argv
for the Python interpreter.
EDIT:
Real life example for a Qt application:
I take part in the developed a Qt networking application. It can run under 2 mutually exclusive modes:
- "normal" mode,
- or "spy mode": this is special because it will required network
administrator privileges for some low-level operations.
So I added a CLI -s/--spy-mode
CLI options to it. These is an optional argv
.
At the beginning of the application code, I check for this argv
-s/--spy-mode
CLI options
- If run in "normal" mode without this option, the GUI elements related
to "spy" mode are simply not even displayed to the user, nor any of
its class instanciated. That is clean, because otherwise it would
fail miserably anyway in many object instanciation/methods, with
errors all over the place, since the low-level calls would fail
anyway, and then I'd exit with a non-zero return code. That is not
good. If you might fail, fail ASAP.
- If launched in "spy" mode using this
argv
options, the first things
I do in my code is check that the calling user do actually have such
"network administrator" privileges, and then 1/ if he does not, issue
an explicit error message/popup window explaining the "you should
have blablabla privilege, blablabal try sudo blablabla", and then
exit with a non-zero return code, or 2/ if the user does indeed have
the required privilege, offer the special "spy mode" GUI elements and
put them to use, no problem (and hide most of the GUI "normal mode"
elements, meaningless in this mode of operation).
This is what argc/argv
are good for.
You don't need to use sys.argv in a PyQt application.
It's only really useful if you want to use command-line arguments. If you don't, you can just pass in an empty list:
app = QtGui.QApplication([])
When you do use sys.argv
, the first argument is automatically set to the script name, and Qt will use this to set the applicationName(). The list of arguments can be accessed later via the arguments() method:
# test.py
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
print('ARGS: %s' % app.arguments())
print('NAME: %r' % app.applicationName())
Output:
$ python test.py -f foo
ARGS: ['test.py', '-f', 'foo']
NAME: 'test.py'
But note that some pre-defined arguments are handled internally by Qt, and will be automatically removed from the arguments:
$ python test.py -f foo -stylesheet=style.qss
ARGS: ['test.py', '-f', 'foo']
NAME: 'test.py'
sys.argv
is not PyQt4 specific. It contains all the command line arguments that were used to start the program in the form of a list.
For example when you start ./test.py arg1 arg2 sys.argv
would contain:
sys.argv[0] == "./test.py"
sys.argv[1] == "arg1"
sys.argv[2] == "arg2"
And with this you could count the number of arguments, this will include the name of the program itself as shown above:
len(sys.argv)
sys.argv
contains all the command-line arguments that were passed to the program when it was launched. The constructor of QApplication
needs these launch options in some circumstances, such as debugging.