[TH] PyQt5

บทความนี้เป็นตัวอย่างการเปิดหน้าต่างและใช้ปุ่มเพื่อตอบสนอง PyQt5 ซึ่งเป็นพื้นฐานเบื้องต้นของการใช้คอมโพเนนท์อื่น ๆ ต่อไป โดยจุดเด่นของ Qt คือ เป็นชุดพัฒนาภาษา C++ ที่ข้ามแพล็ตฟอร์มและมีการครอบการเชื่อมผสานเพื่อใช้กับภาษาต่าง ๆ ได้ เช่น PyQt อันเป็น “The python binding for the Qt cross-platform C++ framework” ที่พัฒนาโดย Riverbank Computing Limited ซึ่งปัจจุบันออกรุ่น PyQt 6.1.1 (2021-06-29)

สิ่งที่ใช้ในการทดลอง

  1. Raspberry Pi 3 หรือ Raspberry Pi 4 หรือเครื่องที่ติดตั้ง Linux/Windows
  2. Python3

เริ่มต้นติดตั้ง

สั่งติดตั้ง package pyqt5 และ pyqt5-sip ด้วยคำสั่งต่อไปนี้

pip install pyqt5 pyqt5-sip

หรือ

pip3 install pyqt5 pyqt5-sip

สร้างหน้าต่าง

ตัวอย่างโปรแกรมเบื้องต้นเป็นดังนี้

#kmqt5-1.py
# -*- coding: UTF-8 -*-
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
 
class MyApp(QWidget):
 
    def __init__(self, title, w, h):
        super().__init__()
        self.setWindowTitle(title)
        self.setGeometry(0, 0, w, h)
        self.show()
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_app = MyApp("PyQt5: สวัสดีคิวท์5", 640, 480)
    sys.exit(app.exec_())

จากโค้ดตัวอย่างจะพบว่า โครงสร้างการเขียนโปรแกรมประกอบไปด้วย 3 ส่วนต่อไปนี้

ส่วนแรกนี้ใช้สำหรับนำเข้าไลบรารีที่ต้องใช้ ซึ่งประกอบไปด้วย QtWidget, QApplication และ QIcon

ส่วนที่ 2 เป็นคลาสของหน้าต่างหลัก ใน __init__( ) เป็นตัวคอนสตรักต์หรือตัวเริ่มทำงานเป็นฟังก์ชันแรกเมื่อคลาสถูกสร้างเป็นวัตถุ ภายในกำหนดชื่อหัวหน้าต่างตามที่รับมาจากอาร์กิวเมนต์พร้อมทั้งกำหนดขนาดของหน้าต่างให้มีความกว้างและสูงเป็น w,h สุดท้ายเป็นการสั่งแสดงหน้าต่าง

ส่วนที่ 3 เป็นส่วนของการเขียนโปรแกรมหลักของผู้เขียนโปรแกรม มีการสร้างตัววัตถุชื่อ app ที่มาจาก Qapplication หลังจากนั้นสร้าง my_app จากคลาสที่สร้างไว้ สุดท้ายสั่งทำงานด้วย app.exec_()

เมื่อสั่งรันโปรแกรมด้วยคำสั่งด้านล่างจะพบผลลัพธ์ของการทำงานดังภาพที่ 1

python kmqt5-1.py

หรือ

python3 kmqt5-1.py

ภาพที่ 1 ผลลัพธ์ของ kmqt5-1.py

สร้างสเตตัสบาร์

สเตตัสบาร์ (status bar) หรือแถบแสดงสถานะเป็นหน้าต่างประเภทหนึ่งที่เป็นหน้าต่างย่อยของหน้าต่างที่สร้างขึ้น โดยปกติมีตำแหน่งอยู่ที่ด้านล่างของหน้าต่างหลัก ในตัวอย่างโปรแกรม kmqt5-2.py มีการใช้ QMainWindow เข้ามาแทนการใช้หน้าต่างแบบ Widget ดังใน kmqt5-1.py เนื่องจากสเตตัสบาร์เป็นหน้าต่างระดับเดียวกับ Widget จึงต้องมีคลาสที่เป็นหน้าต่างหลักเป็นตัวควบคุมหน้าต่างภายใต้โปรแกรมที่เขียน

#kmqt5-2.py
# -*- coding: UTF-8 -*-
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from PyQt5.QtGui import QIcon
 
class MyApp(QMainWindow):
 
    def __init__(self, title, w=640, h=480):
        super().__init__()
        self.setWindowTitle(title)
        self.setGeometry(0, 0, w, h)
        self.statusBar().showMessage('status: สถานะอยู่ตรงนี้!')
        self.show()
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_app = MyApp("PyQt5: สวัสดีคิวท์5 มีสเตตัสบาร์แล้วนะ")
    sys.exit(app.exec_())

จากโปรแกรม kmqt5-2.py เมื่อรันจะแสดงสเตตัสบาร์ดังภาพที่ 2

ภาพที่ 2 ผลลัพธ์การทำงาน kmqt5-2.py

ปุ่มและการตอบสนอง

การสร้างวัตถุประเภทปุ่มต้องอาศัยคล่า QPushButton ซึ่งอยู่ภายใต้คลาส QtWidgets อีกชั้นหนึ่ง โดยขั้นตอนของการสร้างปุ่มประกอบด้วย 5 ขั้นตอน คือ

  1. สร้างวัตถุประเภทปุ่มจากคลาส QPushButton พร้อมทั้งกำหนดข้อความที่ต้องการแสดงบนปุ่มที่สร้าง หรือใช้ setText() สำหรับเปลี่ยนข้อความในภายหลังได้เช่นกัน
  2. กำหนดทูลทิป หรือข้อความที่ลอยอยู่บนปุ่มเมื่อผู้ใช้ย้ายตำแหน่งของเมาส์มาอยู่เหนือปุ่มนั้นด้วย setToolTip()
  3. กำหนดตำแหน่งของปุ่มในหน้าต่างด้วย move(x, y)
  4. สร้างการเชื่อมโยงระหว่างเหตุการณ์ของการกดปุ่มเข้ากับฟังก์ชันตอบสนองด้วย clicked[bool].connect( ฟังก์ชันตอบสนอง )
  5. สร้างฟังก์ชันที่ตอบสนองเหตุการณ์ที่เกิดกับปุ่ม

ตัวอย่างโปรแกรม kmqt5-3.py เป็นการสร้างปุ่มใช้งาน โดยเมื่อทำงานจะได้ผลลัพธ์ดังภาพที่ 3 และ 4

# -*- coding: UTF-8 -*-
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton
from PyQt5.QtGui import QIcon, QColor
 
class MyApp(QWidget):
    def __init__(self, title, w=640, h=480):
        super().__init__()
        self.setWindowTitle(title)
        self.setGeometry(0, 0, w, h)
        self.status = False

        self.my_button = QPushButton("Click-->Yellow::คลิกเพื่อเปลี่ยนเป็นสีเหลือง", self)
        self.my_button.setToolTip("เจอปุ่มก็ต้องกดสินะ!")
        self.my_button.move( 100, 100 )
        self.my_button.clicked[bool].connect(self.on_clicked_my_button)

        self.show()

    def on_clicked_my_button(self):
        source = self.sender()
        if self.status == False:
            self.status = True
            self.setStyleSheet("background-color:yellow;")
            self.my_button.setText("Click-->White::คลิกเพื่อเปลี่ยนเป็นสีขาว")
        else:
            self.status = False
            self.setStyleSheet("background-color:white;")
            self.my_button.setText("Click-->Yellow::คลิกเพื่อเปลี่ยนเป็นสีเหลือง")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_app = MyApp("PyQt5: สวัสดีคิวท์5  มีปุ่มกด ก็ต้องกดปุ่ม")
    sys.exit(app.exec_())
ภาพที่ 3 ผลลัพธ์จากโปรแกรม kmqt5-3.py
ภาพที่ 4 ตัวอย่างผลลัพธ์เมื่อรันบน Raspberry Pi

สรุป

จากตัวอย่างโปรแกรมทั้ง 3 จะเห็นว่า การเขียนโปรแกรมแบบ GUI ด้วยภาษาไพธอนเพื่อใช้ Qt นั้นไม่ซับซ้อน และรองรับการใช้งานภาษาไทยโดยไม่ต้องปรับแก้โค้ดเพิ่มเติม โดยในบทความนี้ผู้อ่านได้เรียนรู้การสร้างหน้าต่าง การใช้สเตตัสบาร์ และการใช้งานปุ่มเพื่อตอบสนองกับผู้ใช้เป็นที่เรียบร้อยแล้ว ซึ่งทีมงานเชื่อว่าคงเป็นพื้นฐานที่ดีสำหรับการศึกษาการเขียนโปรแกรมด้วย PyQt5 ต่อไป หรือปรับเปลี่ยนไปเข้าสู่ PyQt6 ที่ใหม่กว่า สุดท้าย ขอให้สนุกกับการเขียนโปรแกรมครับ

ท่านใดอยากแลกเปลี่ยนสามารถคอมเมนท์ไว้ได้เลยครับ

(C) 2020-2021, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-06-29, 2021-10-07