lunedì 27 agosto 2012

Esempio GUI con PyQt/QtDesigner

Un ulteriore metodo di generare la GUI di prova mediante PyQt e' quella di avvalersi di QtDesigner (da non confondersi con QtCreator che e' relativo al C ed e' un ambiente di sviluppo completo)


Dopo aver composto l'interfaccia grafica si salva il file (.ui) che non e' altro che un Xml con le informazioni di impaginazione



Successivamente con il comando
puic4.bat -x progressbar.uic > progressbar.py

si puo' generare del codice Python/PyQt per creare la finestra come richiesto


il codice autogenerato dal comando sopra riportato
progressbar.py
---------------------------------------------------
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'c:\Documents and Settings\l.innocenti\Desktop\qt\progressbar.ui'
#
# Created: Mon Aug 27 15:05:35 2012
#      by: PyQt4 UI code generator 4.9.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_MainWindow(object):

       
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(351, 117)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.horizontalSlider = QtGui.QSlider(self.centralwidget)
        self.horizontalSlider.setGeometry(QtCore.QRect(10, 10, 331, 21))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
        self.progressBar = QtGui.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(10, 70, 341, 23))
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName(_fromUtf8("progressBar"))
        self.label = QtGui.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(10, 40, 331, 20))
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName(_fromUtf8("label"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.actionCambia_valore = QtGui.QAction(MainWindow)
        self.actionCambia_valore.setObjectName(_fromUtf8("actionCambia_valore"))

        self.retranslateUi(MainWindow)
        QtCore.QObject.connect(self.horizontalSlider, QtCore.SIGNAL("valueChanged(int)"), self.azione)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Progress Bar", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("MainWindow", "0", None, QtGui.QApplication.UnicodeUTF8))
        self.actionCambia_valore.setText(QtGui.QApplication.translate("MainWindow", "cambia_valore", None, QtGui.QApplication.UnicodeUTF8))


    def azione(self):
        s = self.horizontalSlider.value()
        self.label.setText(str(s))
        self.progressBar.setValue(s)


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

---------------------------------------------------
Il problema fondamentale e' che il programma di conversione e' molto buono per generare il codice dei componenti visuali ma non gestisce bene la creazione degli eventi in particolare quelli custom
Per questo motivo e' necessario editare e modificare il codice a mano (evidenziato in giallo)


Progressbar.ui
----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>351</width>
    <height>117</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Progress Bar</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QSlider" name="horizontalSlider">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>10</y>
      <width>331</width>
      <height>21</height>
     </rect>
    </property>
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
   </widget>
   <widget class="QProgressBar" name="progressBar">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>70</y>
      <width>341</width>
      <height>23</height>
     </rect>
    </property>
    <property name="value">
     <number>24</number>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>40</y>
      <width>331</width>
      <height>20</height>
     </rect>
    </property>
    <property name="text">
     <string>0</string>
    </property>
    <property name="alignment">
     <set>Qt::AlignCenter</set>
    </property>
   </widget>
  </widget>
  <action name="actionCambia_valore">
   <property name="text">
    <string>cambia_valore</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>horizontalSlider</sender>
   <signal>sliderMoved(int)</signal>
   <receiver>actionCambia_valore</receiver>
   <slot>trigger()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>175</x>
     <y>20</y>
    </hint>
    <hint type="destinationlabel">
     <x>175</x>
     <y>58</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>


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