การพัฒนาซอฟต์แวร์ด้วย PyQt4 บน Raspberry Pi (Jessie) ตอนที่ 1

Qt เป็น platform ที่ดีอันหนึ่งที่ช่วยให้การพัฒนา Application เป็นไปอย่างรวดเร็ว และ cross platform  ภาษาที่นิยมใช้ใน Qt คือภาษา C++ ครับ แต่สำหรับท่านที่ไม่ถนัด C++ มีอีกหนึ่งทางเลือกคือการใช้ภาษา Python ซึ่งก็มีอยู่สองค่ายคือ PyQt   และ PySide แต่ในบทความนี้ผมจะใช้ของ PyQt ครับเพื่อสร้างทางเลือกอีกทางสำหรับการใช้ Qt กับ Raspberry Pi  และในบทความนี้ผมใช้ Jessie บน Raspbery Pi 2 เป็นตัวทดสอบ

ติดตั้ง PyQt แบบจัด (เกือบ) เต็ม


$ sudo apt-get update
 
$ sudo apt-get install \
pyqt4.qsci-dev \
pyqt5-dev \
python-dbus.mainloop.pyqt5 \
python-guiqwt \
python-kde4-dev \
python-pyqt5 \
python-pyqt5.qtmultimedia \
python-pyqt5.qtopengl \
python-pyqt5.qtpositioning \
python-pyqt5.qtquick \
python-pyqt5.qtsensors \
python-pyqt5.qtserialport \
python-pyqt5.qtsql \
python-pyqt5.qtsvg \
python-pyqt5.qtwebkit \
python-pyqt5.qtwebsockets \
python-pyqt5.qtx11extras \
python-pyqt5.qtxmlpatterns \
python-pyqtgraph \
python-qt4 \
python-qt4-dbus \
python-qt4-dev \
python-qt4-gl \
python-qt4-phonon \
python-qt4-sql \
python-spyderlib \
python-taurus \
python-traitsbackendqt \
python3-dbus.mainloop.pyqt5 \
python3-dbus.mainloop.qt \
python3-pyqt4 \
python3-pyqt4.phonon \
python3-pyqt4.qsci \
python3-pyqt4.qtopengl \
python3-pyqt4.qtsql \
python3-pyqt5 \
python3-pyqt5.qtmultimedia \
python3-pyqt5.qtopengl \
python3-pyqt5.qtpositioning \
python3-pyqt5.qtquick \
python3-pyqt5.qtsensors \
python3-pyqt5.qtserialport \
python3-pyqt5.qtsql \
python3-pyqt5.qtsvg \
python3-pyqt5.qtwebkit \
python3-pyqt5.qtwebsockets \
python3-pyqt5.qtx11extras \
python3-pyqt5.qtxmlpatterns \
python3-pyqtgraph \
python3-spyderlib \
spyder-common \
 
ทั้งหมดนี้จะใช้เนื้อที่ประมาณ 711 MB  และก็ใช้เวลาติดตั้งนานอาจถึงหลายชั่วโมงได้ หากท่านคิดมากเกินไปก็พิจารณาตัดทิ้งได้ แต่ต้องเก็บตัวหลักไว้ คือ python-qt4, python-pyqt5, python-qt-dev, python-pyside,python3-pyqt5,python3-pyqt4   หากคิดว่าจะไม่ใช้ python 2.7 ก็คงเหลือแต่ python3- ไว้ก็ได้  หรือไม่อยากใช้ python3 ก็เหลือแต่ python- ... ก็สุดแล้วแต่  ส่วนตัวแล้วผมถือคติเยอะไว้ก่อน ผมก็เลยเหมาหมด ผลจากการติดตั้งแบบนี้จะได้ซอฟต์แวร์อื่นที่ท่านอาจไม่ต้องการติดมาด้วย เช่น
  • tango db engine จะขอติดตั้งที่ port 10000
  • qt4-designer
  • pymca 
ซึ่งท่านสามารถทำการเอาออกไปด้วยคำสั่ง sudo apt-get remove [application]

Qt4 Designer 

ท่านที่ยังไม่มี Qt4 Designer  สามารถดาวน์โหลดได้จากเว็บนี้ครับ https://www.riverbankcomputing.com/software/pyqt/download
 ท่านที่ใช้ ubuntu desktop ดูจะได้เปรียบนิดหนึ่งเพราะมีใน repository แล้ว ก็เพียงใช้คำสั่ง

$ sudo apt-get install qt4-designer

สำหรับวิธีการใช้งาน ผมจะทิ้งไว้ให้อ่านกันเองนะครับ เพราะมีรายละเอียดเยอะมาก หากท่านมีความคุ้นเคยกับ visual tools อื่นมาก่อนแล้วก็พอจะเดาทางการทำงานออกได้ไม่ยาก ครับ http://doc.qt.io/qt-4.8/designer-layouts.html


ตัวอย่างการพัฒนาโปรแกรม


1. ออกแบบหน้าตา Application บน PC ด้วย Qt-Designer

ผมสร้าง Application เครื่องคิดเลขขึ้นมาตามรูปครับ สร้างเสร็จแล้ว บันทึกไว้ในชื่อ calculator_demo.ui


สิ่งที่ได้จากขั้นตอนนี้คือ

1. รูปแบบหน้าตาของ Application หรือ User Interface
2. ชื่อตัวแปรและ Object ต่าง ๆ ในโปรแกรม
3. User interface file (*.ui) ซึ่งเป็น XML file

ตัวอย่างบางส่วนของเนื้อหาใน user interface file ที่ได้จาก Qt4 Designer



2. การเรียกใช้ user interface file ด้วย pyqt มีสองทางเลือกครับ

2.1 เรียกใช้โดยตรง


import sys
from PyQt4 import QtCore, QtGui, uic

Ui_MainWindow, QtBaseClass = uic.loadUiType("calculator_demo.ui")

class MyApp(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self):

        QtGui.QMainWindow.__init__(self)

        Ui_MainWindow.__init__(self)

        self.setupUi(self)

        

if __name__ == "__main__":

    app = QtGui.QApplication(sys.argv)

    window = MyApp()

    window.show()

    sys.exit(app.exec_())


อธิบาย :



Ui_MainWindow, QtBaseClass = uic.loadUiType("calculator_demo.ui")

คำสั่งในบรรทัดนี้ให้ uic (เป็น user interface module ของ PyQt) ทำการ load user interface file เข้ามาแล้วทำการ compile ในหน่วยความจำ เพื่อให้ PyQt รู้จักตัวแปรทั้งหมด


class MyApp(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self):

        QtGui.QMainWindow.__init__(self)

        Ui_MainWindow.__init__(self)

        self.setupUi(self)

        
เป็นการสร้าง Class ชื่อ MyApp ขึ้นมา ซึ่งเป็น Window รับหน้าที่นำเอาข้อมูลใน user interface ไฟล์มาแสดงบนหน้าจอ 



if __name__ == "__main__":

    app = QtGui.QApplication(sys.argv)

    window = MyApp()

    window.show()

    sys.exit(app.exec_())


เป็นคำสั่งให้โปรแกรมทั้งหมดเริ่มทำงาน

2.2 การ compile ให้เป็น python code
PyQt มี utility ชื่อ pyuic4 และ pyuic5 สำหรับ PyQt4 และ PyQt5 ตามลำดับ สองตัวนี้ต้องติดตั้งเพิ่มเข้าไป ผมไม่ทราบว่า OS อื่นมีให้ติดตั้งหรือไม่ แต่บน Linux มีให้ติดตั้งครับ ถ้าไม่แน่ใจก็สามารถเขียนโปรแกรม Python ง่าย ๆ เพื่อทำงานแทนก็ได้


from PyQt4 import uic
fin = open('path to your ui file','r')
fout = open('your target python file','w')
uic.compileUi(fin,fout,execute=False)
fin.close()
fout.close()

ผลลัพธ์ที่ได้จากเรียกใช้ script นี้จะได้ python code ของ user interface file ของเราสำหรับทำงานกับ PyQt4 ครับ  



บางส่วนของ User interface ในรูปแบบของ Python code ที่ได้จากการ compile
 หลังจากนี้เราก็จะสามารถเรียกใช้ User interface class จาก Application ได้แล้ว

import sys
from PyQt4 import QtCore, QtGui
from calculator_demo_ui import Ui_MainWindow

class CalculatorDemo(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
       
def main():
    app = QtGui.QApplication(sys.argv)
    calculator = CalculatorDemo()
    calculator.show()
    sys.exit(app.exec_())

if __name__ == "__main__" :
    main()




อธิบาย



from calculator_demo_ui import Ui_MainWindow


บรรทัดนี้เป็นการ import ตัว user interface class เข้าไปใน application สังเกตุว่าชื่อ class ต้องตรงกับที่มีใน user interface file



class CalculatorDemo(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)



เราต้องสร้าง class  สำหรับตัว Application หลักขึ้นมา และนำเอา user interface class เข้ามาไว้ในตัว application



def main():
    app = QtGui.QApplication(sys.argv)
    calculator = CalculatorDemo()
    calculator.show()
    sys.exit(app.exec_())

if __name__ == "__main__" :
    main()

ส่วนนี้เป็นการเรียกตัว Application ขึ้นมาแสดงบนหน้าจอครับ 

สรุปขั้นตอนการทำงานก็เป็นตามแผนภาพนี้


และเมื่อทำตามขั้นตอนทั้งหมดนี้แล้วก็จะได้ผลตามวิดีโอนี้





ไฟล์ที่ใช้ในบทความนี้ดาวน์โหลดได้ที่ : https://drive.google.com/file/d/0B-7jlCLBFvNsS2ZiMFplVHFwQmM/view?usp=sharing
Previous
Next Post »