# Python Programming/PyQt4

**WARNING: The examples on this page are a mixture of PyQt3 and PyQt4 -
use with caution!**

This tutorial aims to provide a hands-on guide to learn the basics of
building a small Qt4 application in Python.

To follow this tutorial, you should have basic Python knowledge.
However, knowledge of Qt4 is not necessary. I\'m using Linux in these
examples and am assuming you already have a working installation of
Python and PyQt4. To test this, open a Python shell (by typing
\'Python\' in a console to start the interactive interpreter) and type:

`>>> import PyQt4`

If no error message appears, you should be ready to go.

The examples in this tutorial as easy as possible, showing useful ways
to write and structure your program. It is important that you read the
source code of the example files, most of the explanations are in the
code. The best way to get comfortable with PyQt is play around with the
examples and try to change things.

## Hello, world!

Let\'s start easy: popping up a window and displaying something. The
following small program will pop up a window showing \"Hello, world!\".

``` python
 #!/usr/bin/env python

 import sys
 from PyQt4 import Qt

 # We instantiate a QApplication passing the arguments of the script to it:
 a = Qt.QApplication(sys.argv)

 # Add a basic widget to this application:
 # The first argument is the text we want this QWidget to show, the second
 # one is the parent widget. Since Our "hello" is the only thing we use (the
 # so-called "MainWidget", it does not have a parent.
 hello = Qt.QLabel("Hello, World")

 # ... and that it should be shown.
 hello.show()

 # Now we can start it.
 a.exec_()
```

About 7 lines of code, and that\'s about as easy as it can get.

## A Button

Let\'s add some interaction! We\'ll replace the label saying \"Hello,
World!\" with a button and assign an action to it. This assignment is
done by connecting a **signal**, an event which is sent out when the
button is pushed, to a **slot**, which is an action, normally a function
that is run in the case of that event.

``` python
#!/usr/bin/env python

import sys
from PyQt4 import Qt

a = Qt.QApplication(sys.argv)

# Our function to call when the button is clicked
def sayHello():
    print ("Hello, World!")

# Instantiate the button
hellobutton = Qt.QPushButton("Say 'Hello world!'")

# And connect the action "sayHello" to the event "button has been clicked"
hellobutton.clicked.connect(sayHello)

# The rest is known already...
#a.setMainWidget(hellobutton)
hellobutton.show()
a.exec_()
```

You can imagine that coding this way is not scalable nor the way you\'ll
want to continue working. So let\'s make that stuff pythonic, adding
structure and actually using object-orientation in it. We create our own
application class, derived from a QApplication and put the customization
of the application into its methods: One method to build up the widgets
and a slot which contains the code that\'s executed when a signal is
received.

``` python
#!/usr/bin/env python

import sys
from PyQt4 import Qt

class HelloApplication(Qt.QApplication):
    def __init__(self, args):
        """ In the constructor we're doing everything to get our application
            started, which is basically constructing a basic QApplication by
            its __init__ method, then adding our widgets and finally starting
            the exec_loop."""
        Qt.QApplication.__init__(self, args)
        self.addWidgets()

    def addWidgets(self):
        """ In this method, we're adding widgets and connecting signals from
            these widgets to methods of our class, the so-called "slots"
        """
        self.hellobutton = Qt.QPushButton("Say 'Hello world!'")
        self.hellobutton.clicked.connect(self.slotSayHello)
        self.hellobutton.show()

    def slotSayHello(self):
        """ This is an example slot, a method that gets called when a signal is
            emitted """
        print ("Hello, World!")

# Only actually do something if this script is run standalone, so we can test our
# application, but we're also able to import this program without actually running
# any code.
if __name__ == "__main__":
    app = HelloApplication(sys.argv)
    app.exec_()
```

## GUI Coding

\... so we want to use Qt3 Designer for creating our GUI. In the
picture, you can see a simple GUI, with in green letters the names of
the widgets. What we are going to do is We compile the .ui file from Qt
designer into a python class We subclass that class and use it as our
mainWidget This way, we\'re able to change the user interface afterwards
from Qt designer, without having it messing around in the code we added.

`pyuic4 testapp_ui.ui -o testapp_ui.py`

makes a Python file from it which we can work with.

The way our program works can be described like this: We fill in the
lineedit Clicking the add button will be connected to a method that
reads the text from the lineedit, makes a listviewitem out of it and
adds that to our listview. Clicking the deletebutton will delete the
currently selected item from the listview. Here\'s the heavily commented
code (only works in PyQt3):

``` python
#!/usr/bin/env python

from testapp_ui import TestAppUI
from qt import *
import sys

class HelloApplication(QApplication):
    def __init__(self, args):
        """ In the constructor we're doing everything to get our application
            started, which is basically constructing a basic QApplication by
            its __init__ method, then adding our widgets and finally starting
            the exec_loop."""
        QApplication.__init__(self, args)

        # We pass None since it's the top-level widget, we could in fact leave
        # that one out, but this way it's easier to add more dialogs or widgets.
        self.maindialog = TestApp(None)

        self.setMainWidget(self.maindialog)
        self.maindialog.show()
        self.exec_loop()

class TestApp(TestAppUI):
    def __init__(self, parent):
        # Run the parent constructor and connect the slots to methods.
        TestAppUI.__init__(self, parent)
        self._connectSlots()

        # The listview is initially empty, so the deletebutton will have no effect,
        # we grey it out.
        self.deletebutton.setEnabled(False)

    def _connectSlots(self):
        # Connect our two methods to SIGNALS the GUI emits.
        self.addbutton.clicked.connect(self._slotAddClicked)
        self.deletebutton.clicked.connect(self._slotDeleteClicked)

    def _slotAddClicked(self):
        # Read the text from the lineedit,
        text = self.lineedit.text()
        # if the lineedit is not empty,
        if len(text):
            # insert a new listviewitem ...
            lvi = QListViewItem(self.listview)
            # with the text from the lineedit and ...
            lvi.setText(0,text)
            # clear the lineedit.
            self.lineedit.clear()

            # The deletebutton might be disabled, since we're sure that there's now
            # at least one item in it, we enable it.
            self.deletebutton.setEnabled(True)

    def _slotDeleteClicked(self):
        # Remove the currently selected item from the listview.
        self.listview.takeItem(self.listview.currentItem())

        # Check if the list is empty - if yes, disable the deletebutton.
        if self.listview.childCount() == 0:
            self.deletebutton.setEnabled(False)

if __name__ == "__main__":
    app = HelloApplication(sys.argv)
```

also this code is useful and it works on PyQt4 and it has many useful
options

``` python
#!/usr/bin/env python
# Copyright (c) 2008-10 Qtrac Ltd. All rights reserved.
# This program or module is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 2 of the License, or
# version 3 of the License, or (at your option) any later version. It is
# provided for educational purposes and is distributed in the hope that
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
#
#
#   Versions
#
# 1.0.1 Fixed bug reported by Brian Downing where paths that contained
#       spaces were not handled correctly.
# 1.0.2 Fixed bug reported by Ben Thompson that if the UIC program
#       fails, no problem was reported; I try to report one now.
# 1.1.0 Added Remember path option; if checked the program starts with
#       the last used path, otherwise with the current directory, unless
#       overridden on the command line
# 1.1.1 Changed default path on Windows to match PyQt 4.4
# 1.2.1 Changed import style + bug fixes
# 1.2.2 Added stderr to error message output as per Michael Jackson's
#       suggestion
# 1.2.3 Tried to make the paths work on Mac OS X
# 1.2.4 Added more options
# 1.2.5 Use "new-style" connections (src.signal.connect(target.slot) instead of
#       src.connect(src, SIGNAL("signal()"), target.slot)) and improve PEP-8
#       compliance

from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future_builtins import *

import os
import platform
import stat
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

__version__ = "1.2.5"

Windows = sys.platform.lower().startswith(("win", "microsoft"))

class OptionsForm(QDialog):
    def __init__(self, parent=None):
        super(OptionsForm, self).__init__(parent)

        settings = QSettings()
        if sys.platform.startswith("darwin"):
            pyuic4Label = QLabel("pyuic4 (pyuic.py)")
        else:
            pyuic4Label = QLabel("pyuic4")
        self.pyuic4Label = QLabel(settings.value("pyuic4",
                QVariant(PYUIC4)).toString())
        self.pyuic4Label.setFrameStyle(QFrame.StyledPanel|
                                       QFrame.Sunken)
        pyuic4Button = QPushButton("py&uic4...")
        pyrcc4Label = QLabel("pyrcc4")
        self.pyrcc4Label = QLabel(settings.value("pyrcc4",
                QVariant(PYRCC4)).toString())
        self.pyrcc4Label.setFrameStyle(QFrame.StyledPanel|
                                       QFrame.Sunken)
        pyrcc4Button = QPushButton("p&yrcc4...")
        pylupdate4Label = QLabel("pylupdate4")
        self.pylupdate4Label = QLabel(settings.value("pylupdate4",
                QVariant(PYLUPDATE4)).toString())
        self.pylupdate4Label.setFrameStyle(QFrame.StyledPanel|
                                           QFrame.Sunken)
        pylupdate4Button = QPushButton("&pylupdate4...")
        lreleaseLabel = QLabel("lrelease")
        self.lreleaseLabel = QLabel(settings.value("lrelease",
                QVariant("lrelease")).toString())
        self.lreleaseLabel.setFrameStyle(QFrame.StyledPanel|
                                         QFrame.Sunken)
        lreleaseButton = QPushButton("&lrelease...")
        toolPathGroupBox = QGroupBox("Tool Paths")

        pathsLayout = QGridLayout()
        pathsLayout.addWidget(pyuic4Label, 0, 0)
        pathsLayout.addWidget(self.pyuic4Label, 0, 1)
        pathsLayout.addWidget(pyuic4Button, 0, 2)
        pathsLayout.addWidget(pyrcc4Label, 1, 0)
        pathsLayout.addWidget(self.pyrcc4Label, 1, 1)
        pathsLayout.addWidget(pyrcc4Button, 1, 2)
        pathsLayout.addWidget(pylupdate4Label, 2, 0)
        pathsLayout.addWidget(self.pylupdate4Label, 2, 1)
        pathsLayout.addWidget(pylupdate4Button, 2, 2)
        pathsLayout.addWidget(lreleaseLabel, 3, 0)
        pathsLayout.addWidget(self.lreleaseLabel, 3, 1)
        pathsLayout.addWidget(lreleaseButton, 3, 2)
        toolPathGroupBox.setLayout(pathsLayout)

        resourceModuleNamesGroupBox = QGroupBox(
                "Resource Module Names")
        qrcFiles = bool(int(settings.value("qrc_resources", "1").toString()))
        self.qrcRadioButton = QRadioButton("&qrc_file.py")
        self.qrcRadioButton.setChecked(qrcFiles)
        self.rcRadioButton = QRadioButton("file_&rc.py")
        self.rcRadioButton.setChecked(not qrcFiles)

        radioLayout = QHBoxLayout()
        radioLayout.addWidget(self.qrcRadioButton)
        radioLayout.addWidget(self.rcRadioButton)
        resourceModuleNamesGroupBox.setLayout(radioLayout)

        self.pyuic4xCheckBox = QCheckBox("Run pyuic4 with -&x "
                " to make forms stand-alone runable")
        x = bool(int(settings.value("pyuic4x", "0").toString()))
        self.pyuic4xCheckBox.setChecked(x)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|
                                     QDialogButtonBox.Cancel)

        layout = QVBoxLayout()
        layout.addWidget(toolPathGroupBox)
        layout.addWidget(resourceModuleNamesGroupBox)
        layout.addWidget(self.pyuic4xCheckBox)
        layout.addWidget(buttonBox)
        self.setLayout(layout)

        pyuic4Button.clicked.connect(lambda: self.setPath("pyuic4"))
        pyrcc4Button.clicked.connect(lambda: self.setPath("pyrcc4"))
        pylupdate4Button.clicked.connect(lambda: self.setPath("pylupdate4"))
        lreleaseButton.clicked.connect(lambda: self.setPath("lrelease"))
        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)

        self.setWindowTitle("Make PyQt - Options")

    def accept(self):
        settings = QSettings()
        settings.setValue("pyuic4", QVariant(self.pyuic4Label.text()))
        settings.setValue("pyrcc4", QVariant(self.pyrcc4Label.text()))
        settings.setValue("pylupdate4",
                QVariant(self.pylupdate4Label.text()))
        settings.setValue("lrelease", QVariant(self.lreleaseLabel.text()))
        settings.setValue("qrc_resources",
                "1" if self.qrcRadioButton.isChecked() else "0")
        settings.setValue("pyuic4x",
                "1" if self.pyuic4xCheckBox.isChecked() else "0")
        QDialog.accept(self)

    def setPath(self, tool):
        if tool == "pyuic4":
            label = self.pyuic4Label
        elif tool == "pyrcc4":
            label = self.pyrcc4Label
        elif tool == "pylupdate4":
            label = self.pylupdate4Label
        elif tool == "lrelease":
            label = self.lreleaseLabel
        path = QFileDialog.getOpenFileName(self,
                "Make PyQt - Set Tool Path", label.text())
        if path:
            label.setText(QDir.toNativeSeparators(path))

class Form(QMainWindow):
    def __init__(self):
        super(Form, self).__init__()

        pathLabel = QLabel("Path:")
        settings = QSettings()
        rememberPath = settings.value("rememberpath",
                QVariant(True if Windows else False)).toBool()
        if rememberPath:
            path = (unicode(settings.value("path").toString()) or
                    os.getcwd())
        else:
            path = (sys.argv[1] if len(sys.argv) > 1 and
                    QFile.exists(sys.argv[1]) else os.getcwd())
        self.pathLabel = QLabel(path)
        self.pathLabel.setFrameStyle(QFrame.StyledPanel|
                                     QFrame.Sunken)
        self.pathLabel.setToolTip("The relative path; all actions will "
                "take place here,
and in this path's subdirectories "
                "if the Recurse checkbox is checked")
        self.pathButton = QPushButton("&Path...")
        self.pathButton.setToolTip(self.pathLabel.toolTip().replace(
                "The", "Sets the"))
        self.recurseCheckBox = QCheckBox("&Recurse")
        self.recurseCheckBox.setToolTip("Clean or build all the files "
                "in the path directory,
and all its subdirectories, "
                "as deep as they go.")
        self.transCheckBox = QCheckBox("&Translate")
        self.transCheckBox.setToolTip("Runs pylupdate4 on all "
                "<tt>.py</tt> and <tt>.pyw</tt> files in conjunction "
                "with each <tt>.ts</tt> file.
Then runs "
                "lrelease on all <tt>.ts</tt> files to produce "
                "corresponding <tt>.qm</tt> files.
The "
                "<tt>.ts</tt> files must have been created initially by "
                "running pylupdate4
directly on a <tt>.py</tt> "
                "or <tt>.pyw</tt> file using the <tt>-ts</tt> option.")
        self.debugCheckBox = QCheckBox("&Dry Run")
        self.debugCheckBox.setToolTip("Shows the actions that would "
                "take place but does not do them.")
        self.logBrowser = QTextBrowser()
        self.logBrowser.setLineWrapMode(QTextEdit.NoWrap)
        self.buttonBox = QDialogButtonBox()
        menu = QMenu(self)
        optionsAction = menu.addAction("&Options...")
        self.rememberPathAction = menu.addAction("&Remember path")
        self.rememberPathAction.setCheckable(True)
        self.rememberPathAction.setChecked(rememberPath)
        aboutAction = menu.addAction("&About")
        moreButton = self.buttonBox.addButton("&More",
                QDialogButtonBox.ActionRole)
        moreButton.setMenu(menu)
        moreButton.setToolTip("Use More->Tool paths to set the "
                "paths to the tools if they are not found by default")
        self.buildButton = self.buttonBox.addButton("&Build",
                QDialogButtonBox.ActionRole)
        self.buildButton.setToolTip("Runs pyuic4 on all "
                "<tt>.ui</tt> "
                "files and pyrcc4 on all <tt>.qrc</tt> files "
                "that are out-of-date.
Also runs pylupdate4 "
                "and lrelease if the Translate checkbox is "
                "checked.")
        self.cleanButton = self.buttonBox.addButton("&Clean",
                QDialogButtonBox.ActionRole)
        self.cleanButton.setToolTip("Deletes all <tt>.py</tt> files that "
                "were generated from <tt>.ui</tt> and <tt>.qrc</tt> "
                "files,
i.e., all files matching <tt>qrc_*.py</tt>, "
                "<tt>*_rc.py</tt> and <tt>ui_*.py.")
        quitButton = self.buttonBox.addButton("&Quit",
                QDialogButtonBox.RejectRole)

        topLayout = QHBoxLayout()
        topLayout.addWidget(pathLabel)
        topLayout.addWidget(self.pathLabel, 1)
        topLayout.addWidget(self.pathButton)
        bottomLayout = QHBoxLayout()
        bottomLayout.addWidget(self.recurseCheckBox)
        bottomLayout.addWidget(self.transCheckBox)
        bottomLayout.addWidget(self.debugCheckBox)
        bottomLayout.addStretch()
        bottomLayout.addWidget(self.buttonBox)
        layout = QVBoxLayout()
        layout.addLayout(topLayout)
        layout.addWidget(self.logBrowser)
        layout.addLayout(bottomLayout)
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        aboutAction.triggered.connect(self.about)
        optionsAction.triggered.connect(self.setOptions)
        self.pathButton.clicked.connect(self.setPath)
        self.buildButton.clicked.connect(self.build)
        self.cleanButton.clicked.connect(self.clean)
        quitButton.clicked.connect(self.close)

        self.setWindowTitle("Make PyQt")

    def closeEvent(self, event):
        settings = QSettings()
        settings.setValue("rememberpath",
                QVariant(self.rememberPathAction.isChecked()))
        settings.setValue("path", QVariant(self.pathLabel.text()))
        event.accept()

    def about(self):
        QMessageBox.about(self, "About Make PyQt",
                """Make PyQt v {0}

Copyright © 2007-10 Qtrac Ltd.
                All rights reserved.

This application can be used to build PyQt
                applications.
                It runs pyuic4, pyrcc4, pylupdate4, and lrelease as
                required, although pylupdate4 must be run directly to
                create the initial .ts files.

Python {1} - Qt {2} - PyQt {3} on {4}""".format(
                __version__, platform.python_version(),
                QT_VERSION_STR, PYQT_VERSION_STR,
                platform.system()))

    def setPath(self):
        path = QFileDialog.getExistingDirectory(self,
                "Make PyQt - Set Path", self.pathLabel.text())
        if path:
            self.pathLabel.setText(QDir.toNativeSeparators(path))

    def setOptions(self):
        dlg = OptionsForm(self)
        dlg.exec_()

    def build(self):
        self.updateUi(False)
        self.logBrowser.clear()
        recurse = self.recurseCheckBox.isChecked()
        path = unicode(self.pathLabel.text())
        self._apply(recurse, self._build, path)
        if self.transCheckBox.isChecked():
            self._apply(recurse, self._translate, path)
        self.updateUi(True)

    def clean(self):
        self.updateUi(False)
        self.logBrowser.clear()
        recurse = self.recurseCheckBox.isChecked()
        path = unicode(self.pathLabel.text())
        self._apply(recurse, self._clean, path)
        self.updateUi(True)

    def updateUi(self, enable):
        for widget in (self.buildButton, self.cleanButton,
                self.pathButton, self.recurseCheckBox,
                self.transCheckBox, self.debugCheckBox):
            widget.setEnabled(enable)
        if not enable:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        else:
            QApplication.restoreOverrideCursor()
            self.buildButton.setFocus()

    def _apply(self, recurse, function, path):
        if not recurse:
            function(path)
        else:
            for root, dirs, files in os.walk(path):
                for dir in sorted(dirs):
                    function(os.path.join(root, dir))

    def _make_error_message(self, command, process):
        err = ""
        ba = process.readAllStandardError()
        if not ba.isEmpty():
            err = ": " + str(QString(ba))
        return "FAILED: %s%s" % (command, err)

    def _build(self, path):
        settings = QSettings()
        pyuic4 = unicode(settings.value("pyuic4",
                                        QVariant(PYUIC4)).toString())
        pyrcc4 = unicode(settings.value("pyrcc4",
                                        QVariant(PYRCC4)).toString())
        prefix = unicode(self.pathLabel.text())
        pyuic4x = bool(int(settings.value("pyuic4x", "0").toString()))
        if not prefix.endswith(os.sep):
            prefix += os.sep
        failed = 0
        process = QProcess()
        for name in os.listdir(path):
            source = os.path.join(path, name)
            target = None
            if source.endswith(".ui"):
                target = os.path.join(path,
                                    "ui_" + name.replace(".ui", ".py"))
                command = pyuic4
            elif source.endswith(".qrc"):
                if bool(int(settings.value("qrc_resources", "1").toString())):
                    target = os.path.join(path,
                                        "qrc_" + name.replace(".qrc", ".py"))
                else:
                    target = os.path.join(path, name.replace(".qrc", "_rc.py"))
                command = pyrcc4
            if target is not None:
                if not os.access(target, os.F_OK) or (
                   os.stat(source)[stat.ST_MTIME] >
                   os.stat(target)[stat.ST_MTIME]):
                    args = ["-o", target, source]
                    if command == PYUIC4 and pyuic4x:
                        args.insert(0, "-x")
                    if (sys.platform.startswith("darwin") and
                        command == PYUIC4):
                        command = sys.executable
                        args = [PYUIC4] + args
                    msg = ("converted " + source +
                           " to " + target +
                           "")
                    if self.debugCheckBox.isChecked():
                        msg = "# " + msg + ""
                    else:
                        process.start(command, args)
                        if (not process.waitForFinished(2 * 60 * 1000) or
                            not QFile.exists(target)):
                            msg = self._make_error_message(command,
                                                           process)
                            failed += 1
                    self.logBrowser.append(msg.replace(prefix, ""))
                else:
                    self.logBrowser.append(""
                            "# {0} is up-to-date".format(
                            source.replace(prefix, "")))
                QApplication.processEvents()
        if failed:
            QMessageBox.information(self, "Make PyQt - Failures",
                    "Try manually setting the paths to the tools "
                    "using More->Options")

    def _clean(self, path):
        prefix = unicode(self.pathLabel.text())
        if not prefix.endswith(os.sep):
            prefix += os.sep
        deletelist = []
        for name in os.listdir(path):
            target = os.path.join(path, name)
            source = None
            if (target.endswith(".py") or target.endswith(".pyc") or
                target.endswith(".pyo")):
                if name.startswith("ui_") and not name[-1] in "oc":
                    source = os.path.join(path, name[3:-3] + ".ui")
                elif name.startswith("qrc_"):
                    if target[-1] in "oc":
                        source = os.path.join(path, name[4:-4] + ".qrc")
                    else:
                        source = os.path.join(path, name[4:-3] + ".qrc")
                elif name.endswith(("_rc.py", "_rc.pyo", "_rc.pyc")):
                    if target[-1] in "oc":
                        source = os.path.join(path, name[:-7] + ".qrc")
                    else:
                        source = os.path.join(path, name[:-6] + ".qrc")
                elif target[-1] in "oc":
                    source = target[:-1]
                if source is not None:
                    if os.access(source, os.F_OK):
                        if self.debugCheckBox.isChecked():
                            self.logBrowser.append(""
                                    "# delete {0}".format(
                                    target.replace(prefix, "")))
                        else:
                            deletelist.append(target)
                    else:
                        self.logBrowser.append(""
                                "will not remove "
                                "'{0}' since `{1}' not found"
                                .format(target.replace(prefix, ""),
                                source.replace(prefix, "")))
        if not self.debugCheckBox.isChecked():
            for target in deletelist:
                self.logBrowser.append("deleted "
                        "{0}".format(
                        target.replace(prefix, "")))
                os.remove(target)
                QApplication.processEvents()

    def _translate(self, path):
        prefix = unicode(self.pathLabel.text())
        if not prefix.endswith(os.sep):
            prefix += os.sep
        files = []
        tsfiles = []
        for name in os.listdir(path):
            if name.endswith((".py", ".pyw")):
                files.append(os.path.join(path, name))
            elif name.endswith(".ts"):
                tsfiles.append(os.path.join(path, name))
        if not tsfiles:
            return
        settings = QSettings()
        pylupdate4 = unicode(settings.value("pylupdate4",
                             QVariant(PYLUPDATE4)).toString())
        lrelease = unicode(settings.value("lrelease",
                           QVariant(LRELEASE)).toString())
        process = QProcess()
        failed = 0
        for ts in tsfiles:
            qm = ts[:-3] + ".qm"
            command1 = pylupdate4
            args1 = files + ["-ts", ts]
            command2 = lrelease
            args2 = ["-silent", ts, "-qm", qm]
            msg = "updated {0}".format(
                    ts.replace(prefix, ""))
            if self.debugCheckBox.isChecked():
                msg = "# {0}".format(msg)
            else:
                process.start(command1, args1)
                if not process.waitForFinished(2 * 60 * 1000):
                    msg = self._make_error_message(command1, process)
                    failed += 1
            self.logBrowser.append(msg)
            msg = "generated {0}".format(
                    qm.replace(prefix, ""))
            if self.debugCheckBox.isChecked():
                msg = "# {0}".format(msg)
            else:
                process.start(command2, args2)
                if not process.waitForFinished(2 * 60 * 1000):
                    msg = self._make_error_message(command2, process)
                    failed += 1
            self.logBrowser.append(msg)
            QApplication.processEvents()
        if failed:
            QMessageBox.information(self, "Make PyQt - Failures",
                    "Try manually setting the paths to the tools "
                    "using More->Options")

app = QApplication(sys.argv)
PATH = unicode(app.applicationDirPath())
if Windows:
    PATH = os.path.join(os.path.dirname(sys.executable),
                        "Lib/site-packages/PyQt4")
    if os.access(os.path.join(PATH, "bin"), os.R_OK):
        PATH = os.path.join(PATH, "bin")
if sys.platform.startswith("darwin"):
    i = PATH.find("Resources")
    if i > -1:
        PATH = PATH[:i] + "bin"
PYUIC4 = os.path.join(PATH, "pyuic4")
if sys.platform.startswith("darwin"):
    PYUIC4 = os.path.dirname(sys.executable)
    i = PYUIC4.find("Resources")
    if i > -1:
        PYUIC4 = PYUIC4[:i] + "Lib/python2.6/site-packages/PyQt4/uic/pyuic.py"
PYRCC4 = os.path.join(PATH, "pyrcc4")
PYLUPDATE4 = os.path.join(PATH, "pylupdate4")
LRELEASE = "lrelease"
if Windows:
    PYUIC4 = PYUIC4.replace("/", "\\") + ".bat"
    PYRCC4 = PYRCC4.replace("/", "\\") + ".exe"
    PYLUPDATE4 = PYLUPDATE4.replace("/", "\\") + ".exe"
app.setOrganizationName("Qtrac Ltd.")
app.setOrganizationDomain("qtrac.eu")
app.setApplicationName("Make PyQt")
if len(sys.argv) > 1 and sys.argv[1] == "-c":
    settings = QSettings()
    settings.setValue("pyuic4", QVariant(PYUIC4))
    settings.setValue("pyrcc4", QVariant(PYRCC4))
    settings.setValue("pylupdate4", QVariant(PYLUPDATE4))
    settings.setValue("lrelease", QVariant(LRELEASE))
form = Form()
form.show()
app.exec_()
```

## Useful to Know

Creating the GUI in Qt Designer not only makes creating the GUI easier,
but it\'s also a great learning tool. You can test what a widget looks
like, see what\'s available in Qt, and have a look at properties you
might want to use.

The C++ API documentation is also a very useful (read: necessary) tool
when working with PyQt. The API translation is straightforward, and
after a little experience, you\'ll find the developers API docs one of
the tools you really need. When working from KDE, konqueror\'s default
shortcut is qt:\[widgetname\], so \[alt\]+\[F2\], \"qt:qbutton directly
takes you to the right API documentation page. Trolltech\'s doc section
has much more documentation which you might want to have a look at.

The first 3 examples in this tutorial have been created using PyQt4, the
last one uses syntax that only works with PyQt3.

Note: The previous version of this page (applicable to pyqt3) is/was
available at <http://vizzzion.org/?id=pyqt>.

This document is published under the GNU Free Documentation
License.

fr:PyQt


# Python Programming/Dbus

In Linux, **Dbus** is a way for processes to communicate with each
other. For example, programs like
Pidgin instant
messenger allow other programs to find out or change the user\'s status
(Available, Away, etc). Another example is the
network-manager service
that publishes which internet connection is active. Programs that
sometimes connect to the internet can then pick the best time to
download updates to the system.

## Buses

Messages are sent along buses. Services attach themselves to these
buses, and allow clients to pass messages to and from them.

There are two main buses, the **system bus** and **session bus**.
Services on the system bus affect the whole system, such as providing
information about the network or disk drives. Services on the session
bus provide access to programs running on the desktop, like Pidgin.

``` python
import dbus

sys_bus = dbus.SystemBus()
```

## Objects and interfaces

Services attached to a bus can be contacted using their **well-known
name**. While this could be any string, the format is normally that of a
reverse domain name: an example for a spreadsheet program called
\"CalcProgram\" from \"My Corp Inc.\" could be
\"com.mycorp.CalcProgram\".

Services publish objects using slash-separated paths (this is similar to
webpages). Someone on dbus can request an object if they know this path.

The object passed back is not a full object: it just refers to the
service\'s copy of the object. It is called a **proxy object**.

``` python
proxy_for_cell_a2 = sys_bus.get_object('com.mycorp.CalcProgram', '/spreadsheet1/cells/a2')
```

Before the proxy object can be used, we need to specify what type of
object it is. We do this by creating an interface object.

``` python
cell_a2 = dbus.Interface(proxy_for_cell_a2, 'com.mycorp.CalcProgram.SpreadsheetCell')
```

Whatever methods are set up for this type of object can be called:

``` python
cell_a2.getContents()
```

  Name                      Example                                  Description
  ------------------------- ---------------------------------------- ---------------------------------------------
  service well known name   com.mycorp.CalcProgram                   Identifies the application
  path of an object         /spreadsheet1/cells/a2                   Identifies an object published by a service
  interface                 com.mycorp.CalcProgram.SpreadsheetCell   Identifies what type of object we expect

## dbus-python examples

These examples have been tested with dbus-python 0.83.0. Older library
versions may not have the same interface.

Calling an interface\'s methods / Listing HAL Devices:

``` python
import dbus

bus = dbus.SystemBus()
hal_manager_object = bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
hal_manager_interface = dbus.Interface(hal_manager_object, 'org.freedesktop.Hal.Manager')

# calling method upon interface
print hal_manager_interface.GetAllDevices()

# accessing a method through 'get_dbus_method' through proxy object by specifying interface
method = hal_manager_object.get_dbus_method('GetAllDevices', 'org.freedesktop.Hal.Manager')
print(method())

# calling method upon proxy object by specifying the interface to use
print( hal_manager_object.GetAllDevices(dbus_interface='org.freedesktop.Hal.Manager'))
```

Introspecting an object:

``` python
import dbus

bus = dbus.SystemBus()
hal_manager_object = bus.get_object(
    'org.freedesktop.Hal',          # service
    '/org/freedesktop/Hal/Manager'  # published object
)

introspection_interface = dbus.Interface(
    hal_manager_object,
    dbus.INTROSPECTABLE_IFACE,
)

# Introspectable interfaces define a property 'Introspect' that
# will return an XML string that describes the object's interface
interface = introspection_interface.Introspect()
print(interface)
```

Avahi:

``` python
import dbus

sys_bus = dbus.SystemBus()

# get an object called / in org.freedesktop.Avahi to talk to
raw_server = sys_bus.get_object('org.freedesktop.Avahi', '/')

# objects support interfaces. get the org.freedesktop.Avahi.Server interface to our org.freedesktop.Avahi object.
server = dbus.Interface(raw_server, 'org.freedesktop.Avahi.Server')

# The so-called documentation is at /usr/share/avahi/introspection/Server.introspect
print(server)
print(server.GetVersionString())
print(server.GetHostName())
```

## pydbus examples

These examples have been tested with pydbus 0.2 and 0.3.

Calling an interface\'s methods / Listing systemd units:

``` python
from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get(
    '.systemd1' # service name - names starting with . automatically get org.freedesktop prepended.
    # no object path - it'll be set to the service name transformed to the path format (/org/freedesktop/systemd1)
)

for unit in systemd.ListUnits()[0]:
    print(unit)
```

Introspecting an object:

``` python
from pydbus import SystemBus

bus = SystemBus()
systemd = bus.get('.systemd1')

# Introspectable interfaces define a property 'Introspect' that
# will return an XML string that describes the object's interface
print(systemd.Introspect()[0])

# Introspection data is automatically converted to Python's help system data
help(systemd)
```

Avahi:

``` python
from pydbus import SystemBus

bus = SystemBus()

# get an object called / in org.freedesktop.Avahi to talk to
avahi = bus.get('.Avahi', '/')

# See the object's API
help(avahi)

print(avahi.GetVersionString())
print(avahi.GetHostName())
```

## References

-   dbus-python
    tutorial,
    dbus.freedesktop.org, Simon McVittie, 2006-06-14
-   pydbus
    README.rst,
    github.com
-   DbusExamples,
    wiki.python.org
-   D-Bus Howto,
    developer.pidgin.im
-   Rough notes: Python and
    D-Bus,
    archived version, A.M. Kuchling, 2007, originally at www.amk.ca


# Python Programming/matplotlib

matplotlib is a Python library that allows Python to be used like
Matlab, visualizing data on the fly. It is able to create plots,
histograms, power spectra, bar charts, errorcharts, scatterplots, etc.
It can be used from normal Python and also from iPython.

Examples:

Plot a data series that represents the square function:

``` py
from matplotlib import pyplot as plt
data = [x * x for x in range(20)]
plt.plot(data)
plt.show()
```

Plot a data series that represents the square function but in reverse
order, by providing not only the series of the y-axis values but also
the series of x-axis values:

``` py
from matplotlib import pyplot as plt
datax = range(20)
datax.reverse()
datay = [x * x for x in range(20)]
plt.plot(datax, datay)
plt.show()
```

Plot the square function, setting the limits for the y-axis:

``` py
from matplotlib import pyplot as plt
data = [x * x for x in range(20)]
plt.ylim(-500, 500) # Set limits of y-axis
plt.plot(data)
plt.show()
```

## Links

-   matplotlib, matplotlib.org
-   Pyplot
    tutorial,
    matplotlib.org


# Python Programming/Sorted Container Types

Python does not provide modules for *sorted* set and dictionary data
types as part of its standard library. This is a concious decision on
the part of Guido van Rossum, et al. to preserve \"one obvious way to do
it.\" Instead, Python delegates this task to third-party libraries that
are available on the Python Package Index. These libraries use various
techniques to maintain list, dict, and set types in sorted order.
Maintaining order using a specialized data structure can avoid very slow
behavior (quadratic run-time) in the naive approach of editing and
constantly re-sorting.

Third-party modules supporting sorted containers:

-   SortedContainers - Pure-Python implementation that is fast-as-C
    implementations. Implements sorted list, dict, and set. Testing
    includes 100% code coverage and hours of stress. Documentation
    includes full API reference, performance
    comparison,
    and contributing/development guidelines. License: Apache2.
-   rbtree - Provides a fast, C-implementation for sorted dict and set
    data types. Based on a red-black tree implementation.
-   treap - Provides a sorted dict data type. Uses a treap for
    implementation and improves performance using Cython.
-   bintrees - Provides several tree-based implementations for dict and
    set data types. Fastest implementations are based on AVL and
    Red-Black trees. Implemented in C. Extends the conventional API to
    provide set operations for dict data types.
-   banyan - Provides a fast, C-implementation for dict and set data
    types.
-   skiplistcollections - Pure-Python implementation based on skip-lists
    providing a limited API for dict and set data types.
-   blist - Provides sorted list, dict and set data types based on the
    \"blist\" data type, a B-tree implementation. Implemented in Python
    and C.

## External links

-   SortedContainers,
    pypi.python.org
-   rbtree, pypi.python.org
-   treap, pypi.python.org
-   bintrees, pypi.python.org
-   Banyan, pypi.python.org
-   skiplistcollections,
    pypi.python.org
-   blist, pypi.python.org


# Python Programming/Excel

Python has multiple 3rd party libraries for reading and writing
Microsoft Excel spreadsheet files, including .xls and .xlsx.

For working with .xls files, there is *xlrd* for reading and *xlwt* for
writing.

For working with .xlsx files, there is *xlrd* for reading, *openpyxl*
for reading and writing, and *XlsxWriter* and *PyExcelerate* for
writing.

To interact with the Excel application and create Python-based add-ins:
*xlwings*, *xlOil*, *PyXLL* (commercial).

## xlrd

Supports reading .xls Excel files. Support for .xlsx files was removed
in xlrd version 2.0.0 from Dec 2020 due to security concerns, but is
still available in xlrd version 1.2.0 from Dec 2018. License: BSD.

Example:

``` Python
import xlrd
workbook = xlrd.open_workbook("MySpreadsheet.xls")
#for sheet in workbook.sheets(): # Loads all the sheets, unlike workbook.sheet_names()
for sheetName in workbook.sheet_names(): # Sheet iteration by name
  print("Sheet name:", sheetName)
  sheet = workbook.sheet_by_name(sheetName)
  for rowno in range(sheet.nrows):
    for colno in range(sheet.ncols):
      cell = sheet.cell(rowno, colno)
      print(str(cell.value)) # Output as a string
      if cell.ctype == xlrd.XL_CELL_DATE:
        dateTuple = xlrd.xldate_as_tuple(cell.value, workbook.datemode)
        print(dateTuple) # E.g. (2017, 1, 1, 0, 0, 0)
        mydate = xlrd.xldate.xldate_as_datetime(cell.value, workbook.datemode)
        print(mydate) # In xlrd 0.9.3
      print()

for sheetno in range(workbook.nsheets): # Sheet iteration by index
  sheet = workbook.sheet_by_index(sheetno)
  print("Sheet name:", sheet.name)
  for notekey in sheet.cell_note_map: # In xlrd 0.7.2
    print("Note AKA comment text:", sheet.cell_note_map[notekey].text)

print(xlrd.formula.colname(1)) # Column name such as A or AD, here 'B'
```

Links:

-   xlrd, pypi.python.org
-   xlrd 1.2.0, pypi.python.org
-   xlrd documentation,
    readthedocs.io
-   xlrd API
    documentation,
    readthedocs.io
-   Python: xlrd discerning dates from
    floats,
    stackoverflow.com
-   xlrd.biffh.XLRDError: Excel xlsx file; not
    supported,
    11 Dec 2020, stackoverflow.com
-   xlrd 2
    released,
    11 Dec 2020, groups.google.com

## xlwt

Supports writing .xls files. License: BSD.

Links:

-   xlwt, pypi.python.org
-   xlwt documentation,
    readthedocs.io

## openpyxl

Supports reading and writing .xlsx Excel files. Does not support .xls
files. License: MIT.

Reading a workbook:

``` python
from openpyxl import load_workbook
workbook = load_workbook("MyNewWorkbook.xlsx")
for worksheet in workbook.worksheets:
  print("==%s==" % worksheet.title)
  for row in worksheet: # For each cell in each row
    for cell in row:
      print(cell.row, cell.column, cell.value) # E.g. 1 A Value
  for cell in worksheet["A"]: # For each cell in column A
    print(cell.value)
  print(worksheet["A1"].value) # A single cell
  print(worksheet.cell(column=1, row=1).value) # A1 value as well
```

Creating a new workbook:

``` python
from openpyxl import Workbook
workbook = Workbook()
worksheet = workbook.worksheets[0]
worksheet['A1'] = 'String value'
worksheet['A2'] = 42 # Numerical value
worksheet.cell(row=3, column=1).value = "New A3 Value"
workbook.save("MyNewWorkbook.xlsx") # Overrides if it exists
```

Changing an existing workbook:

``` python
from openpyxl import load_workbook
workbook_name = 'MyWorkbook.xlsx'
workbook = load_workbook(workbook_name)
worksheet = workbook.worksheets[0]
worksheet['A1'] = "String value"
workbook.save(workbook_name)
```

Links:

-   openpyxl, pypi.org
-   openpyxl - A Python library to read/write Excel 2010 xlsx/xlsm
    files, readthedocs.io

## XlsxWriter

Supports writing of .xlsx files. License: BSD.

Links:

-   XlsxWriter, pypi.org
-   Creating Excel files with Python and
    XlsxWriter, readthedocs.io

## PyExcelerate

Supports writing .xlsx files. License: BSD.

Links:

-   PyExcelerate, pypi.org

## xlutils

Supports various operations and queries on .xls files; depends on xlrd
and xlwt. License: MIT.

Links:

-   xlutils, pypi.org

## xlOil

Supports creation of Python-based Excel add-ins. Requires Python 3.6 or
later; requires Excel 2010 or later installed. Supports: global and
local scope worksheet functions, ribbon customisation, custom task
panes, RTD/async functions, *numpy*, *matplotlib*, *pandas*, *jupyter*.
Low overhead function calls due to use of the Excel\'s C-API and
embedded in-process Python

Examples:

Create a function to add one day to a date:

``` Python
import datetime as dt
@xloil.func
def pyTestDate(x: dt.datetime) -> dt.datetime:
    return x + dt.timedelta(days=1)
```

Create a function which give a live ticking clock in an cell (uses RTD):

``` python
@xloil.func
async def pyTestAsyncGen(secs):
    while True:
        await asyncio.sleep(secs)
        yield datetime.datetime.now()
```

Links:

-   xlOil, pypi.org
-   xloil, readthedocs.io

## pywin32

Supports access to Windows applications via Windows Component Object
Model (COM). Thus, on Windows, if Excel is installed, PyWin32 lets you
call it from Python and let it do various things. You can install
PyWin32 by downloading a .exe installer from SourceForge, where it is
currently hosted.

Links:

-   3.4.1.
    PyWin32,
    docs.python.org
-   pywin32, pypi.org
-   Python for Windows Extensions
    files,
    sourceforge.net
-   Python Excel Mini
    Cookbook,
    pythonexcels.com

## External links

-   Working with Excel Files in Python,
    python-excel.org \-- has links to source code repositories (GitHub,
    etc.) for the packages


# Python Programming/MS Word

Microsoft Word documents of the .docx format can be created or changed
using python-docx 3rd party module.

The .doc format can be worked with on Windows using PyWin32 via COM
interface, provided Word is installed. An example:

``` Python
import win32com.client
wordapp = win32com.client.gencache.EnsureDispatch("Word.Application")
# wordapp.Visible = False
worddoc = wordapp.Documents.Open(r"C:\MyFile.doc")
wdFormatHTML = 8
worddoc.SaveAs(r"C:\MyFile.html", FileFormat=wdFormatHTML)
worddoc.ActiveWindow.Close()
# wordapp.Application.Quit(-1) - No need to quit; Word quits when its last window is closed
```

## External links

-   python-docx,
    pypi.python.org
-   python-docx,
    readthedocs.io


# Python Programming/Extending with C

Python modules can be written in pure Python but they can also be
written in the C language. The following shows how to extend Python with
C.

## Using the Python/C API

### A minimal example

To illustrate the mechanics, we will create a minimal extension module
containing a single function that outputs \"Hello\" followed by the name
passed in as the first parameter.

We will first create the C source code, placing it to **hellomodule.c**:

``` c
#include <Python.h>

static PyObject*
say_hello(PyObject* self, PyObject* args)
{
    const char* name;

    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    printf("Hello %s!\n", name);

    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] =
{
     {"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
     {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inithello(void)
{
     (void) Py_InitModule("hello", HelloMethods);
}
```

Then we will need a setup file, **setup.py**:

``` python
from distutils.core import setup, Extension

module1 = Extension('hello', sources = ['hellomodule.c'])

setup (name = 'PackageName',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1])
```

Then we can build the module using a procedure whose details depends on
the operating system and the compiler suite.

#### Building with GCC for Linux

Before our module can be compiled, you must install the Python
development headers if you have not already. On Debian and Debian-based
systems such as Ubuntu, these can be installed with the following
command:

``` bash
$ sudo apt install python-dev
```

On openSUSE, the required package is called `python-devel` and can be
installed with `zypper`:

``` bash
$ sudo zypper install python-devel
```

Now that `Python.h` is available, we can compile the module source code
we created in the previous section as follows:

``` bash
$ python setup.py build
```

The will compile the module to a file called `hello.so` in
`build/lib.linux-i686-`*`x`*`.`*`y`*.

#### Building with GCC for Microsoft Windows

Microsoft Windows users can use MinGW to compile
the extension module from the command line. Assuming `gcc` is in the
path, you can build the extension as follows:

`python setup.py build -cmingw32`

The above will produce file `hello.pyd`, a Python Dynamic Module,
similar to a DLL. The file will land in `build\lib.win32-`*`x`*`.`*`y`*.

An alternate way of building the module in Windows is to build a DLL.
(This method does not need an extension module file). From `cmd.exe`,
type:

`gcc -c  hellomodule.c -I/Python`*`XY`*`/include`\
`gcc -shared hellomodule.o -L/Python`*`XY`*`/libs -lpython`*`XY`*` -o hello.dll`

where *XY* represents the version of Python, such as \"24\" for version
2.4.

#### Building using Microsoft Visual C++

With VC8, distutils is broken. Therefore, we will use cl.exe from a
command prompt instead:

`cl /LD hellomodule.c /Ic:\Python24\include c:\Python24\libs\python24.lib /link/out:hello.dll`

#### Using the extension module

Change to the subdirectory where the file hello.so resides. In an
interactive Python session you can use the module as follows.

`>>> import hello`\
`>>> hello.say_hello("World")`\
`Hello World!`

### A module for calculating Fibonacci numbers

In this section, we present a module for Fibonacci numbers, thereby
expanding on the minimal example above. Compared to the minimal example,
what is worth noting is the use of \"i\" in PyArg_ParseTuple() and
Py_BuildValue().

The C source code in (fibmodule.c):

``` c
#include <Python.h>

int
_fib(int n)
{
    if (n < 2)
        return n;
    else
        return _fib(n-1) + _fib(n-2);
}

static PyObject*
fib(PyObject* self, PyObject* args)
{
    int n;

    if (!PyArg_ParseTuple(args, "i", &n))
        return NULL;

    return Py_BuildValue("i", _fib(n));
}

static PyMethodDef FibMethods[] = {
    {"fib", fib, METH_VARARGS, "Calculate the Fibonacci numbers."},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
initfib(void)
{
    (void) Py_InitModule("fib", FibMethods);
}
```

The build script (setup.py):

``` python
from distutils.core import setup, Extension

module1 = Extension('fib', sources = ['fibmodule.c'])

setup (name = 'PackageName',
        version = '1.0',
        description = 'This is a demo package',
        ext_modules = [module1])
```

Usage:

`>>> import fib`\
`>>> fib.fib(10)`\
`55`

## Using SWIG

SWIG is a tool that helps a variety of scripting and programming
languages call C and C++ code. SWIG makes creation of C language modules
much more straightforward.

To use SWIG, you need to get it up and running first.

You can install it on an Ubuntu system as follows:

`$ sudo apt-get install swig`\
`$ sudo apt-get install python-dev`

To get SWIG for Windows, you can use binaries available from the SWIG
download page.

Once you have SWIG, you need to create the module source file and the
module interface file:

hellomodule.c:

``` c
#include <stdio.h>

void say_hello(const char* name) {
    printf("Hello %s!\n", name);
}
```

hello.i:

``` c
%module hello
extern void say_hello(const char* name);
```

Then we let SWIG do its work:

`swig -python hello.i`

The above produces files hello.py and hello_wrap.c.

The next step is compiling; substitute /usr/include/python2.4/ with the
correct path to Python.h for your setup:

`gcc -fpic -c hellomodule.c hello_wrap.c -I/usr/include/python2.4/`

As the last step, we do the linking:

`gcc -shared hellomodule.o hello_wrap.o -o _hello.so -lpython`

The module is used as follows:

`>>> import hello`\
`>>> hello.say_hello("World")`\
`Hello World!`

## External links

-   Extending and Embedding the Python
    Interpreter,
    python.org
-   Python/C API Reference
    Manual, python.org
-   SWIG, swig.org
-   Download SWIG, swig.org


# Python Programming/Extending with C++

There are different ways to extend Python with C and C++ code:

-   In plain C, using Python.h
-   Using Swig
-   Using Boost.Python, optionally with Py++ preprocessing
-   Using pybind11
-   Using ../Cython/.

This page describes Boost.Python. Before the emergence of Cython, it was
the most comfortable way of writing C++ extension
modules.

Boost.Python comes bundled with the Boost C++ Libraries. To install it
on an Ubuntu system, you might need to run the following commands

`$ sudo apt-get install libboost-python-dev `\
`$ sudo apt-get install python-dev`

## A Hello World Example

### The C++ source code (hellomodule.cpp)

``` cpp
#include <iostream>

using namespace std;

void say_hello(const char* name) {
    cout << "Hello " <<  name << "!\n";
}

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE(hello)
{
    def("say_hello", say_hello);
}
```

### setup.py

``` python
#!/usr/bin/env python

from distutils.core import setup
from distutils.extension import Extension

setup(name="PackageName",
    ext_modules=[
        Extension("hello", ["hellomodule.cpp"],
        libraries = ["boost_python"])
    ])
```

Now we can build our module with

`python setup.py build`

The module \`hello.so\` will end up in e.g \`build/lib.linux-i686-2.4\`.

### Using the extension module

Change to the subdirectory where the file \`hello.so\` resides. In an
interactive python session you can use the module as follows.

`>>> import hello`\
`>>> hello.say_hello("World")`\
`Hello World!`

## An example with CGAL

Some, but not all, functions of the CGAL library already have Python
bindings. Here an example is provided for a case without such a binding
and how it might be implemented. The example is taken from the CGAL
Documentation.

``` Cpp
// test.cpp
using namespace std;

/* PYTHON */
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
namespace python = boost::python;

/* CGAL */
#include <CGAL/Cartesian.h>
#include <CGAL/Range_segment_tree_traits.h>
#include <CGAL/Range_tree_k.h>

typedef CGAL::Cartesian<double> K;
typedef CGAL::Range_tree_map_traits_2<K, char> Traits;
typedef CGAL::Range_tree_2<Traits> Range_tree_2_type;

typedef Traits::Key Key;
typedef Traits::Interval Interval;

Range_tree_2_type *Range_tree_2 = new Range_tree_2_type;

void create_tree()   {

  typedef Traits::Key Key;
  typedef Traits::Interval Interval;

  std::vector<Key> InputList, OutputList;
  InputList.push_back(Key(K::Point_2(8,5.1), 'a'));
  InputList.push_back(Key(K::Point_2(1.0,1.1), 'b'));
  InputList.push_back(Key(K::Point_2(3,2.1), 'c'));

  Range_tree_2->make_tree(InputList.begin(),InputList.end());
  Interval win(Interval(K::Point_2(1,2.1),K::Point_2(8.1,8.2)));
  std::cout << "\n Window Query:\n";
  Range_tree_2->window_query(win, std::back_inserter(OutputList));
  std::vector<Key>::iterator current=OutputList.begin();
  while(current!=OutputList.end()){
      std::cout << "  " << (*current).first.x() << "," << (*current).first.y()
           << ":" << (*current).second << std::endl;
      current++;
    }
  std::cout << "\n Done\n";
}

void initcreate_tree() {;}

using namespace boost::python;
BOOST_PYTHON_MODULE(test)
{
    def("create_tree", create_tree, "");
}
```

``` Cpp
// setup.py
#!/usr/bin/env python

from distutils.core import setup
from distutils.extension import Extension

setup(name="PackageName",
    ext_modules=[
        Extension("test", ["test.cpp"],
        libraries = ["boost_python"])
    ])
```

We then compile and run the module as follows:

`$ python setup.py build`\
`$ cd build/lib*`\
`$ python`\
`>>> import test`\
`>>> test.create_tree()`\
`Window Query:`\
` 3,2.1:c`\
` 8,5.1:a`\
`Done`\
`>>>`

## Handling Python objects and errors

One can also handle more complex data, e.g. Python objects like lists.
The attributes are accessed with the extract function executed on the
objects \"attr\" function output. We can also throw errors by telling
the library that an error has occurred and returning. In the following
case, we have written a C++ function called \"afunction\" which we want
to call. The function takes an integer N and a vector of length N as
input, we have to convert the python list to a vector of strings before
calling the function.

``` Cpp
#include <vector>
using namespace std;

void _afunction_wrapper(int N, boost::python::list mapping) {

    int mapping_length = boost::python::extract<int>(mapping.attr("__len__")());
    //Do Error checking, the mapping needs to be at least as long as N
    if (mapping_length < N) {
        PyErr_SetString(PyExc_ValueError,
            "The string mapping must be at least of length N");
        boost::python::throw_error_already_set();
        return;
    }

    vector<string> mystrings(mapping_length);
    for (int i=0; i<mapping_length; i++) {
        mystrings[i] = boost::python::extract<char const *>(mapping[i]);
    }

   //now call our C++ function
   _afunction(N, mystrings);

}

using namespace boost::python;
BOOST_PYTHON_MODULE(c_afunction)
{
    def("afunction", _afunction_wrapper);
}
```

## External links

-   Boost.Python, boost.org
-   pybind11, pypi.org


# Python Programming/Extending with Pyrex

Pyrex is a compiler of Python-like source code to the C language,
intended to make it relatively easy for Python programmers to write fast
Python extension modules without having to learn the C language.

../Cython/ is an actively developed derivative
of Pyrex. Pyrex is no longer actively developed, the last stable release
being from 2010.

Links:

-   Pyrex - a Language for Writing Python Extension
    Modules,
    cosc.canterbury.ac.nz
-   Pyrex (programming
    language) "wikilink"),
    en.wikipedia.org


# Python Programming/Extending with ctypes

ctypes1 is a foreign function
interface module for Python
(included with Python 2.5 and above), which allows you to load in
dynamic libraries and call C functions. This is not technically
extending Python, but it serves one of the primary reasons for extending
Python: to interface with external C code.

## Basics

A library is loaded using the `ctypes.CDLL` function. After you load the
library, the functions inside the library are already usable as regular
Python calls. For example, if we wanted to forego the standard Python
print statement and use the standard C library function, `printf`, you
would use this:

``` python
from ctypes import *
libName = 'libc.so' # If you're on a UNIX-based system
libName = 'msvcrt.dll' # If you're on Windows
libc = CDLL(libName)
libc.printf("Hello, World!\n")
```

Of course, you must use the libName line that matches your operating
system, and delete the other. If all goes well, you should see the
infamous Hello World string at your console.

## Getting Return Values

ctypes assumes, by default, that any given function\'s return type is a
signed integer of native size. Sometimes you don\'t want the function to
return anything, and other times, you want the function to return other
types. Every ctypes function has an attribute called `restype`. When you
assign a ctypes class to `restype`, it automatically casts the
function\'s return value to that type.

### Common Types

  ctypes name   C type               Python type   Notes
  ------------- -------------------- ------------- -----------------
  None          void                 None          the None object
  c_bool        C99 \_Bool           bool
  c_byte        signed char          int
  c_char        signed char          str           length of one
  c_char_p      char \*              str
  c_double      double               float
  c_float       float                float
  c_int         signed int           int
  c_long        signed long          long
  c_longlong    signed long long     long
  c_short       signed short         long
  c_ubyte       unsigned char        int
  c_uint        unsigned int         int
  c_ulong       unsigned long        long
  c_ulonglong   unsigned long long   long
  c_ushort      unsigned short       int
  c_void_p      void \*              int
  c_wchar       wchar_t              unicode       length of one
  c_wchar_p     wchar_t \*           unicode


# Python Programming/Extending with Perl

It is possible to call Perl functions and modules in Python. One way to
do that is the PyPerl Module. It
is not developed actively any more and for it to work in newer versions,
one has to use
this
version and apply the patches.

``` python
import perl
perl.eval( "use lib './' ")
perl.require( 'Module::ModuleName' )

obj = perl.callm("new", 'Module::ModuleName'  )
obj[ '_attr1' ] = 9
obj[ '_attr2' ] = 42
obj.fxn1()
```

It is thus possible to handle Perl objects, change their attributes and
call their methods.

## See also

-   <http://wiki.python.org/moin/IntegratingPythonWithOtherLanguages#Perl>


# Python Programming/Popularity

The popularity of a programming language is one factor that people
consider when choosing a language for a task or a project. Beware that
even a good programming language can be unpopular.

The popularity of Python can be determined with the help of various
indices, which are not identical to the real popularity in the real
world. While the statistics are linked from the external links section
below, it is advisable that you use them with a grain of salt.

Python is the main scripting language used by Google, per Google Python
Style Guide.

Python is embedded in various software packages to support their
extensibility and automation, including Gimp and Inkscape; see also
Wikipedia\'s W:Python
(programming_language)#Uses#Uses "wikilink")
and W:List of Python software#Embedded as a scripting
language.

## External links

-   Tiobe index, tiobe.com
-   PYPL PopularitY of Programming
    Languages, pypl.github.io
-   RedMonk
    rankings,
    redmonk.com, combines Stack Overflow data with GitHub data
-   The 2015 Top Ten Programming
    Languages,
    spectrum.ieee.org, 2015
-   W:Measuring programming language
    popularity
-   W:Programming languages used in most popular
    websites
-   W:Python
    (programming_language) "wikilink")
-   W:List of Python software
-   Google Python Style
    Guide,
    google.github.io
-   Python Success Stories,
    python.org
-   Organizations using
    Python,
    wiki.python.org


# Python Programming/Links

Web resources:

Python.org:

-   The Python.org documents section
    -   Current Python 2.x documentation
    -   Current Python 3.x documentation
-   Python Wiki at python.org
    -   Python IDEs

Online books:

-   Dive into Python by Mark Pilgrim,
    a free book published under GNU Free Documentation License, with
    around 100 000 words
-   Text Processing in Python, a book by David
    Mertz, published by Addison Wesley
-   Introduction to Python Programming with
    NCLab, a book available as a
    single PDF, with around 44 000 words
-   Invent Your Own Computer Games with
    Python - A complete eBook for total
    beginners available for free under a Creative Commons license.
-   Making Games with Python &
    Pygame - A Creative
    Commons-licensed book that covers the Pygame library.
-   Hacking Secret Ciphers with
    Python - A Creative
    Commons-licensed book for complete beginners with a focus on
    cryptography.

Various:

-   Python Programming
    Tutorials \--
    a list of Python tutorials
-   ActiveState Python
    Cookbook \-- a
    collection of Python recipes
-   Dev Shed\'s Python Tutorials
    \-- a collection of Python articles
-   Python Tutorials at
    awaretek.com
-   Python 101 \-- Introduction to
    Python by
    Dave Kuhlman, around 9000 words
-   Category:Python,
    rosettacode.org


# Python Programming/Library Modules

This is a list of python modules in the standard library as of Python
3.6.

-   \_\_future\_\_: Future statement definitions
-   \_\_main\_\_: The environment where the top-level script is run.
-   \_dummy_thread: Drop-in replacement for the \_thread module.
-   \_thread: Low-level threading API.
-   abc: Abstract base classes according to PEP 3119.
-   aifc: Read and write audio files in AIFF or AIFC format.
-   argparse: Command-line option and argument parsing library.
-   array: Space efficient arrays of uniformly typed numeric values.
-   ast: Abstract Syntax Tree classes and manipulation.
-   asynchat: Support for asynchronous command/response protocols.
-   asyncio: Asynchronous I/O, event loop, coroutines and tasks.
-   asyncore: A base class for developing asynchronous socket handling
    services.
-   atexit: Register and execute cleanup functions.
-   audioop: Manipulate raw audio data.
-   base64: RFC 3548: Base16, Base32, Base64 Data Encodings; Base85 and
    Ascii85
-   bdb: Debugger framework.
-   binascii: Tools for converting between binary and various
    ASCII-encoded binary representations.
-   binhex: Encode and decode files in binhex4 format.
-   bisect: Array bisection algorithms for binary searching.
-   builtins: The module that provides the built-in namespace.
-   bz2: Interfaces for bzip2 compression and decompression.
-   calendar: Functions for working with calendars, including some
    emulation of the Unix cal program.
-   cgi: Helpers for running Python scripts via the Common Gateway
    Interface.
-   cgitb: Configurable traceback handler for CGI scripts.
-   chunk: Module to read IFF chunks.
-   cmath: Mathematical functions for complex numbers.
-   cmd: Build line-oriented command interpreters.
-   code: Facilities to implement read-eval-print loops.
-   codecs: Encode and decode data and streams.
-   codeop: Compile (possibly incomplete) Python code.
-   collections: Container datatypes
-   colorsys: Conversion functions between RGB and other color systems.
-   compileall: Tools for byte-compiling all Python source files in a
    directory tree.
-   concurrent:
-   configparser: Configuration file parser.
-   contextlib: Utilities for with-statement contexts.
-   copy: Shallow and deep copy operations.
-   copyreg: Register pickle support functions.
-   cProfile
-   crypt (Unix): The crypt() function used to check Unix passwords.
-   csv: Write and read tabular data to and from delimited files.
-   ctypes: A foreign function library for Python.
-   curses (Unix): An interface to the curses library, providing
    portable terminal handling.
-   datetime: Basic date and time types.
-   dbm: Interfaces to various Unix \"database\" formats.
-   decimal: Implementation of the General Decimal Arithmetic
    Specification.
-   difflib: Helpers for computing differences between objects.
-   dis: Disassembler for Python bytecode.
-   distutils: Support for building and installing Python modules into
    an existing Python installation.
-   doctest: Test pieces of code within docstrings.
-   dummy_threading: Drop-in replacement for the threading module.
-   email: Package supporting the parsing, manipulating, and generating
    email messages.
-   encodings:
-   ensurepip: Bootstrapping the \"pip\" installer into an existing
    Python installation or virtual environment.
-   enum: Implementation of an enumeration class.
-   errno: Standard errno system symbols.
-   faulthandler: Dump the Python traceback.
-   fcntl (Unix): The fcntl() and ioctl() system calls.
-   filecmp: Compare files efficiently.
-   fileinput: Loop over standard input or a list of files.
-   fnmatch: Unix shell style filename pattern matching.
-   formatter: Deprecated: Generic output formatter and device
    interface.
-   fpectl (Unix): Provide control for floating point exception
    handling.
-   fractions: Rational numbers.
-   ftplib: FTP protocol client (requires sockets).
-   functools: Higher-order functions and operations on callable
    objects.
-   gc: Interface to the cycle-detecting garbage collector.
-   getopt: Portable parser for command line options; support both short
    and long option names.
-   getpass: Portable reading of passwords and retrieval of the userid.
-   gettext: Multilingual internationalization services.
-   glob: Unix shell style pathname pattern expansion.
-   grp (Unix): The group database (getgrnam() and friends).
-   gzip: Interfaces for gzip compression and decompression using file
    objects.
-   hashlib: Secure hash and message digest algorithms.
-   heapq: Heap queue algorithm (a.k.a. priority queue).
-   hmac: Keyed-Hashing for Message Authentication (HMAC) implementation
-   html: Helpers for manipulating HTML.
-   http: HTTP status codes and messages
-   imaplib: IMAP4 protocol client (requires sockets).
-   imghdr: Determine the type of image contained in a file or byte
    stream.
-   imp: Deprecated: Access the implementation of the import statement.
-   importlib: The implementation of the import machinery.
-   inspect: Extract information and source code from live objects.
-   io: Core tools for working with streams.
-   ipaddress: IPv4/IPv6 manipulation library.
-   itertools: Functions creating iterators for efficient looping.
-   json: Encode and decode the JSON format.
-   keyword: Test whether a string is a keyword in Python.
-   lib2to3: the 2to3 library
-   linecache: This module provides random access to individual lines
    from text files.
-   locale: Internationalization services.
-   logging: Flexible event logging system for applications.
-   lzma: A Python wrapper for the liblzma compression library.
-   macpath: Mac OS 9 path manipulation functions.
-   mailbox: Manipulate mailboxes in various formats
-   mailcap: Mailcap file handling.
-   marshal: Convert Python objects to streams of bytes and back (with
    different constraints).
-   math: Mathematical functions (sin() etc.).
-   mimetypes: Mapping of filename extensions to MIME types.
-   mmap: Interface to memory-mapped files for Unix and Windows.
-   modulefinder: Find modules used by a script.
-   msilib (Windows): Creation of Microsoft Installer files, and CAB
    files.
-   msvcrt (Windows): Miscellaneous useful routines from the MS VC++
    runtime.
-   multiprocessing: Process-based parallelism.
-   netrc: Loading of .netrc files.
-   nis (Unix): Interface to Sun\'s NIS (Yellow Pages) library.
-   nntplib: NNTP protocol client (requires sockets).
-   numbers: Numeric abstract base classes (Complex, Real, Integral,
    etc.).
-   operator: Functions corresponding to the standard operators.
-   optparse: Deprecated: Command-line option parsing library.
-   os: Miscellaneous operating system interfaces.
-   ossaudiodev (Linux, FreeBSD): Access to OSS-compatible audio
    devices.
-   parser: Access parse trees for Python source code.
-   pathlib: Object-oriented filesystem paths
-   pdb: The Python debugger for interactive interpreters.
-   pickle: Convert Python objects to streams of bytes and back.
-   pickletools: Contains extensive comments about the pickle protocols
    and pickle-machine opcodes, as well as some useful functions.
-   pipes (Unix): A Python interface to Unix shell pipelines.
-   pkgutil: Utilities for the import system.
-   platform: Retrieves as much platform identifying data as possible.
-   plistlib: Generate and parse Mac OS X plist files.
-   poplib: POP3 protocol client (requires sockets).
-   posix (Unix): The most common POSIX system calls (normally used via
    module os).
-   pprint: Data pretty printer.
-   profile: Python source profiler.
-   pstats: Statistics object for use with the profiler.
-   pty (Linux): Pseudo-Terminal Handling for Linux.
-   pwd (Unix): The password database (getpwnam() and friends).
-   py_compile: Generate byte-code files from Python source files.
-   pyclbr: Supports information extraction for a Python class browser.
-   pydoc: Documentation generator and online help system.
-   queue: A synchronized queue class.
-   quopri: Encode and decode files using the MIME quoted-printable
    encoding.
-   random: Generate pseudo-random numbers with various common
    distributions.
-   re: Regular expression operations.
-   readline (Unix): GNU readline support for Python.
-   reprlib: Alternate repr() implementation with size limits.
-   resource (Unix): An interface to provide resource usage information
    on the current process.
-   rlcompleter: Python identifier completion, suitable for the GNU
    readline library.
-   runpy: Locate and run Python modules without importing them first.
-   sched: General purpose event scheduler.
-   secrets: Generate secure random numbers for managing secrets.
-   select: Wait for I/O completion on multiple streams.
-   selectors: High-level I/O multiplexing.
-   shelve: Python object persistence.
-   shlex: Simple lexical analysis for Unix shell-like languages.
-   shutil: High-level file operations, including copying.
-   signal: Set handlers for asynchronous events.
-   site: Module responsible for site-specific configuration.
-   smtpd: A SMTP server implementation in Python.
-   smtplib: SMTP protocol client (requires sockets).
-   sndhdr: Determine type of a sound file.
-   socket: Low-level networking interface.
-   socketserver: A framework for network servers.
-   spwd (Unix): The shadow password database (getspnam() and friends).
-   sqlite3: A DB-API 2.0 implementation using SQLite 3.x.
-   ssl: TLS/SSL wrapper for socket objects
-   stat: Utilities for interpreting the results of os.stat(),
    os.lstat() and os.fstat().
-   statistics: mathematical statistics functions
-   string: Common string operations.
-   stringprep: String preparation, as per RFC 3453
-   struct: Interpret bytes as packed binary data.
-   subprocess: Subprocess management.
-   sunau: Provide an interface to the Sun AU sound format.
-   symbol: Constants representing internal nodes of the parse tree.
-   symtable: Interface to the compiler\'s internal symbol tables.
-   sys: Access system-specific parameters and functions.
-   sysconfig: Python\'s configuration information
-   syslog (Unix): An interface to the Unix syslog library routines.
-   tabnanny: Tool for detecting white space related problems in Python
    source files in a directory tree.
-   tarfile: Read and write tar-format archive files.
-   telnetlib: Telnet client class.
-   tempfile: Generate temporary files and directories.
-   termios (Unix): POSIX style tty control.
-   test: Regression tests package containing the testing suite for
    Python.
-   textwrap: Text wrapping and filling
-   threading: Thread-based parallelism.
-   time: Time access and conversions.
-   timeit: Measure the execution time of small code snippets.
-   tkinter: Interface to Tcl/Tk for graphical user interfaces
-   token: Constants representing terminal nodes of the parse tree.
-   tokenize: Lexical scanner for Python source code.
-   trace: Trace or track Python statement execution.
-   traceback: Print or retrieve a stack traceback.
-   tracemalloc: Trace memory allocations.
-   tty (Unix): Utility functions that perform common terminal control
    operations.
-   turtle: An educational framework for simple graphics applications
-   turtledemo: A viewer for example turtle scripts
-   types: Names for built-in types.
-   typing: Support for type hints (see PEP 484).
-   unicodedata: Access the Unicode Database.
-   unittest: Unit testing framework for Python.
-   urllib:
-   uu: Encode and decode files in uuencode format.
-   uuid: UUID objects (universally unique identifiers) according to RFC
    4122
-   venv: Creation of virtual environments.
-   warnings: Issue warning messages and control their disposition.
-   wave: Provide an interface to the WAV sound format.
-   weakref: Support for weak references and weak dictionaries.
-   webbrowser: Easy-to-use controller for Web browsers.
-   winreg (Windows): Routines and objects for manipulating the Windows
    registry.
-   winsound (Windows): Access to the sound-playing machinery for
    Windows.
-   wsgiref: WSGI Utilities and Reference Implementation.
-   xdrlib: Encoders and decoders for the External Data Representation
    (XDR).
-   xml: Package containing XML processing modules
-   zipapp: Manage executable python zip archives
-   zipfile: Read and write ZIP-format archive files.
-   zipimport: support for importing Python modules from ZIP archives.
-   zlib: Low-level interface to compression and decompression routines
    compatible with gzip.


# Python Programming/Naming conventions

There are various naming conventions used in Python programs.

PEP 0008 specifies naming conventions for class names (e.g.
GenericTree), package and module names (e.g. generictree and
generic_tree), function and variable names (storestate or store_state;
mixedCase is dispreferred), and more. Google Python Style Guide follows
similar naming conventions.

The above stands in contrast to Java naming convention (e.g. storeState
for method names) and C# naming convention (e.g. StoreState for method
names).

In Python 2, the standard library contains multiple deviations from PEP
0008. For instance, Tkinter module is spelled as Tkinter with capital T;
this was renamed to tkinter in Python 3.

## External links

-   Naming
    Conventions
    in PEP 0008: Style Guide for Python Code, python.org
-   Naming in
    Google Python Style Guide, google.github.io
-   pycodestyle - Python
    style guide checker, pypi.python.org
-   Modules to
    Rename
    in PEP 3108, python.org
-   W:Naming convention
    (programming) "wikilink")


# Ada Programming/All Chapters

------------------------------------------------------------------------

!Ada. Time-tested, safe and
secure.{width="300"}

\_\_NOEDITSECTION\_\_ \_\_TOC\_\_

# Preface

# Basic Ada

# Installing

# Building

# Control Statements

# Type System

# Integer types

# Unsigned integer types

# Enumerations

# Floating point types

# Fixed point types

# Arrays

# Records

# Access types

# Limited types

# Strings

# Subprograms

# Packages

# Input Output

# Exceptions

# Generics

# Tasking

# Object Orientation

# New in Ada 2005

# Containers

# Interfacing

# Coding Standards

# Tips

# Common Errors

# Algorithms

# Chapter 1

# Chapter 6

# Knuth-Morris-Pratt pattern matcher

# Binary Search

# Function overloading

# Mathematical calculations

# Statements

# Variables

# Lexical elements

# Keywords

# Delimiters

# Operators

# Attributes

# Pragmas

# Libraries

# Libraries: Standard

# Libraries: Ada

# Libraries: Interfaces

# Libraries: System

# Libraries: GNAT

# Libraries: Multi-Purpose

# Libraries: Container

# Libraries: GUI

# Libraries: Distributed Systems

# Libraries: Databases

# Libraries: Web

# Libraries: Input Output

# Platform Support

# Platform: Linux

# Platform: Windows

# Platform: Virtual Machines

# Portals

# Tutorials

# Web 2.0

 All Chapters All
Chapters