The tools used

For management and the creation of HMI, the tools used are:

  • PyQt
  • QtDesigner
  • Pyuic

PyQt

PyQt is the Python version of Qt, and an object-oriented framework developed in C + + by a subsidiary of Nokia. Qt allows creating GUIs in Python (in this case with QtDesigner). The libraries offer GUI components (widgets), data access, network connections, thread management, XML parsing… The Qt library (since version 4) is divided into modules. The main modules are:

  • QtCore: for non-graphical features used by other modules;
  • QtGui: for widgets;
  • QtNetwork : pour la programmation réseau ;
  • QtSql: when using SQL database;
  • QtXml: handling and generation of XML files;
  • QtDesigner: to extend the functionality of Qt Designer, the wizard for creating graphical user interfaces;

Example of a window with a button “Hello World! ”:

../_images/hello_world.png

And its associated code:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from PyQt4 import QtGui, QtCore
import sys

app = QtGui.QApplication(sys.argv)
hello = QtGui.QPushButton("Hello World!", None)
hello.show()
app.exec_()

Note

Graphic environment KDE uses the Qt library.

QtDesigner and Pyuic

QtDesigner is the tool provided by the Qt library, which allows a Human Machine Interface (HMI) via a graphical interface. QtDesigner does not generate source code directly but creates backup files of “forms” created with the extension .ui (derived from XML). The module Pyuic (written in Python) generate the Python code of the GUI (“form”) stored in the .ui.

Example

  • Creation of a form with QtDesigner:

    ../_images/exemple_qt.png
  • The recording of the “form” untitled.ui generates a file untitled.ui:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Dialog</class>
     <widget class="QDialog" name="Dialog">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>320</width>
        <height>240</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Dialog</string>
      </property>
      <widget class="QDialogButtonBox" name="buttonBox">
       <property name="geometry">
        <rect>
         <x>10</x>
         <y>200</y>
         <width>301</width>
         <height>32</height>
        </rect>
       </property>
       <property name="orientation">
        <enum>Qt::Horizontal</enum>
       </property>
       <property name="standardButtons">
        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
       </property>
      </widget>
      <widget class="QCalendarWidget" name="calendarWidget">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>10</y>
         <width>312</width>
         <height>172</height>
        </rect>
       </property>
      </widget>
     </widget>
     <resources/>
     <connections>
      <connection>
       <sender>buttonBox</sender>
       <signal>accepted()</signal>
       <receiver>Dialog</receiver>
       <slot>accept()</slot>
       <hints>
        <hint type="sourcelabel">
         <x>248</x>
         <y>254</y>
        </hint>
        <hint type="destinationlabel">
         <x>157</x>
         <y>274</y>
        </hint>
       </hints>
      </connection>
      <connection>
       <sender>buttonBox</sender>
       <signal>rejected()</signal>
       <receiver>Dialog</receiver>
       <slot>reject()</slot>
       <hints>
        <hint type="sourcelabel">
         <x>316</x>
         <y>260</y>
        </hint>
        <hint type="destinationlabel">
         <x>286</x>
         <y>274</y>
        </hint>
       </hints>
      </connection>
     </connections>
    </ui>
  • It remains to generate the python code with Pyuic, the general syntax of puyic4 is:

    >>> pyuic4 [options] LeFichier.ui
    
  • With the following options:

    OPTIONS

    UTILITY

    -h

    [- -help]

    A help message appears on the output

    -version

    The version number is written on the output

    i N

    [- -indent=N]

    The Python source code generated will be indented n spaces default

    If N=0 tabs are used instead of spaces. The default is N=4

    -o Fichier

    [- -output=Fichier]

    Source code is generated in a file that must be given the extension ”. py”

    -p

    [- -preview]

    The interface is dynamically generated, and any Python source code is created

    -x

    [- -execute]

    The generated source code will contain a bit of extra code to be executable

  • It therefore generates Python code with the following command:

    >>> pyuic4 -o MonAppli.py -x untitled.ui
    
  • We obtain the following code:

    # -*- coding: utf-8 -*-
    
    # Form implementation generated from reading ui file 'untitled.ui'
    #
    # Created: Mon Oct 11 16:32:30 2010
    #      by: PyQt4 UI code generator 4.7.4
    #
    # WARNING! All changes made in this file will be lost!
    
    from PyQt4 import QtCore, QtGui
    
    class Ui_Dialog(object):
        def setupUi(self, Dialog):
            Dialog.setObjectName("Dialog")
            Dialog.resize(320, 240)
            self.buttonBox = QtGui.QDialogButtonBox(Dialog)
            self.buttonBox.setGeometry(QtCore.QRect(10, 200, 301, 32))
            self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
            self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
            self.buttonBox.setObjectName("buttonBox")
            self.calendarWidget = QtGui.QCalendarWidget(Dialog)
            self.calendarWidget.setGeometry(QtCore.QRect(0, 10, 312, 172))
            self.calendarWidget.setObjectName("calendarWidget")
    
            self.retranslateUi(Dialog)
            QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept)
            QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject)
            QtCore.QMetaObject.connectSlotsByName(Dialog)
    
        def retranslateUi(self, Dialog):
            Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
    
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        Dialog = QtGui.QDialog()
        ui = Ui_Dialog()
        ui.setupUi(Dialog)
        Dialog.show()
        sys.exit(app.exec_())
    
  • This allows us to run the code and starting the interface:

    >>> python ./MyApplication.py
    

../_images/calendar.png

Organizing IHM files in GWA

Note

  • .ui files are stored in the folder “UI”
  • Images are stored in the folder “images”
In folder “UI”, there is a file .ui per IHM
  • IHM_menu.ui
  • IHM_lieu.ui
  • IHM_AP.ui
  • IHM_mesure.ui
  • IHM_extraction.ui
Plus a file that manages the images used
  • ihm_images.qrc

As seen in the example above must compile these files .ui in .py (and the .qrc). It is therefore necessary to generate the root of the GWA, but also make a change a das of imports. Indeed, the image file that is generated is ihm_images.py (and not ihm_images_rc.py as specified by the .py files self-generated). To facilitate the generation of these files a script was created in the “UI”:

#!/bin/bash

echo "Traitement de \"ihm_images.py\""
pyrcc4 -o ../ihm_images.py ihm_images.qrc

echo "Traitement de \"ihm_AP.py\""
pyuic4 -o ../ihm_AP.py -x IHM_AP.ui
sed -e 's/ihm_images_rc/ihm_images/g' < ../ihm_AP.py > temp && mv -f temp ../ihm_AP.py

echo "Traitement de \"ihm_extraction.py\""
pyuic4 -o ../ihm_extraction.py -x IHM_extraction.ui
sed -e 's/ihm_images_rc/ihm_images/g' < ../ihm_extraction.py > temp && mv -f temp ../ihm_extraction.py

echo "Traitement de \"ihm_lieu.py\""
pyuic4 -o ../ihm_lieu.py -x IHM_lieu.ui
sed -e 's/ihm_images_rc/ihm_images/g' < ../ihm_lieu.py > temp && mv -f temp ../ihm_lieu.py

echo "Traitement de \"ihm_menu.py\""
pyuic4 -o ../ihm_menu.py -x IHM_menu.ui
sed -e 's/ihm_images_rc/ihm_images/g' < ../ihm_menu.py > temp && mv -f temp ../ihm_menu.py

echo "Traitement de \"ihm_mesure.py\""
pyuic4 -o ../ihm_mesure.py -x IHM_mesure.ui
sed -e 's/ihm_images_rc/ihm_images/g' < ../ihm_mesure.py > temp && mv -f temp ../ihm_mesure.py

Table Of Contents

Previous topic

Organization of the DB

Next topic

module: ‘main.py’

This Page