เวลาเราดำเนินการอะไรจากออบเจ็กต์หนึ่งแล้วย่อมต้องการผลจากการกระทำนั้นไปปรากฏยังออบเจ็กต์หนึ่ง (ไม่งั้นจะทำไปทำไม ใช่ไหมครับ) เช่น เราคลิกปุ่มที่กำหนดเป็นปุ่ม Close เราย่อมต้องการให้ปิดหน้าต่างการแสดงผล
ใน Qt มีหลักการว่า เวลาที่เราคลิกนั้นฝั่งผู้ส่ง (Sender) จะเกิด Signal ขึ้นโดยสัญญานที่เกิดขึ้นนั้นจะส่งต่อไปยังผู้รับ (receive) ผ่านฟังค์ชันหนึ่งเราจะเรียกฟังค์ชันนั้นว่า Slot
ที่สำคัญหนึ่ง Signal สามารถส่งไปให้กับหลายออบเจกต์ หรือออบเจ็กต์เดียวหลาย Slot ก็นับว่าสะดวกดี
![]() |
ตัวอย่างในภาพนี้ LineEdit จะส่ง Signal ชื่อ textChanged ไปยัง Slot ชื่อ setText ของ Label และ LineEdit ที่อยู่ด้านล่าง |
หากเราสร้าง Signal และ Slot ผ่าน GUI ของ QtCreator โดยการลากเมาส์จากออบเจ็กต์ไปยังออบเจ็กต์ โดยไม่ได้พิมพ์คำสั่งใน mainwindow.cpp ระบบจะยังไม่สร้างโค้ด จนกว่าเราจะสั่งรันหรือสร้างโปรแกรม ระบบจะสร้างโค้ดโปรแกรมไว้ในไฟล์ ui_mainwindow.h ซึ่งจะอยู่ในโฟลเดอร์ของไฟล์ buil-XXX
ด้วยวิธีการนี้ใครที่เคยใช้ PyQt แล้วแปลงไฟล์ ui ให้เป็นไฟล์ Python คงจะเจอปัญหา Signal/Slot ไม่ถูกแปลงไปเป็นคำสั่ง Python ด้วย ส่วนนี้คงต้องรอตัวแปลงไฟล์เขาอัพเดทกันอีกที
ตัวอย่างดังในรูปต่อไปนี้
![]() |
lineEdit ส่ง Signal ชื่อ textChanged ไปยัง label และ lineEdit_2 |
![]() |
ดูจาก FileSystem/maindow.ui จะเห็นว่ามี connection 2 ส่วน ซึ่งเป็น label และ lineEdit_2 |
![]() |
เมื่อสั่งสร้างโปรแกรมแล้วจะเกิดไฟล์ ui_mainwindow.h ซึ่งแปลงคำสั่งให้เป็นรูปแบบของ Qt Framework อีกทีหนึ่ง |
เขียนคำสั่งใน Signal และ Slot
นอกจากวิธีการใช้ ui แล้ว Qt ยังให้ผู้เขียนสามารถเขียนโปรแกรมโดยตรงในไฟล์ mainwindow.cpp โดยคลิกขวาที่ออบเจ็กต์แล้วคลิกที่เมนู go to slot ระบบจะไปเพิ่มฟังค์ชันใน mainwindow.cpp ให้และให้เราเขียนคำสั่งเพิ่มเติม ซึ่งจะสามารถเพิ่มเติมคำสั่งหรือวิธีการตรวจสอบอื่นๆ ได้มากกว่าสั่งผ่าน gui![]() |
เมื่อคลิก go to slot แล้วจะมีรายการ signal ให้เลือก คลิกเลือก textChanged แล้วคลิกปุ่ม OK |
![]() |
ในไฟล์ mainwindow.cpp จะมีฟังค์ชันชื่อ on_lineEdit_textChanged |
ใช้ฟังค์ชัน connect เพื่อสร้าง signal/slot
อีกวิธีหนึ่งสำหรับการสร้าง signal/slot คือ เขียนผ่านฟังค์ชัน connect โดยตรงในไฟล์ mainwindow.cpp วิธีจะเป็นที่นิยมสำหรับผู้เขียนโปรแกรมที่เน้นเขียนคำสั่งผ่านซอร์สโค้ดไฟล์เป็นหลัก วิธีการดังในรูปด้านล้างนี้![]() |
ฟอร์มที่สร้างใน qtcreator ได้เพิ่ม lineEdit_4 และเขียนชื่อออบเจ็กต์กำกับไว้ด้วย |
![]() |
ในไฟล์ mainwindow.cpp จะเพิ่มคำสั่ง connect เพื่อสร้าง signal และ slot ให้กับ lineEdit |
โดย TextLabel และ lineEdit_2 จะทำงานผ่าน gui โดยคลิกที่ออบเจ็กต์แล้วลากไปวางออบเจ็กต์ใหม่ผ่านทูลบาร์ Edit Signal and Slot
lineEdit_3 จะอัพเดทข้อมูลผ่านการคลิกเมาส์ปุ่มขวาที่ ออบเจ็กต์แล้วเลือกเมนู go to slot เพื่อเขียนฟังค์ชันที่ใช้เป็น slot
lineEdit_4 จะอัพเดทข้อมูลผ่านการเขียนคำสั่งส่งสัญญาณผ่านฟังค์ชัน connect โดยมีรูปแบบดังนี้
connect(sender, SIGNAL(textChanged(QString)), receiver, SLOT(setText(QString)));
หรือ สำหรับ Qt5
connect(sender, &Sender::textChanged, receiver, &Receiver::setText);
สำหรับรูปสุดท้ายแสดงถึงการใช้ connect แบบใหม่ของ Qt5 เขียนดังนี้
connect(ui->lineEdit, &QLineEdit::textChanged, ui->lineEdit_4, &QLineEdit::setText);
โดย sender ก็อ้างอิงไปถึง ui->lineEdit ส่วน receiver คือ ui->lineEdit_4 อธิบายให้ง่ายอีกก็คือ lineEdit ส่ง signal ชื่อ textChanged ไปยัง lineEdit_4 เพื่อเรียกใช้ slot ชื่อ setText
ดังนั้นเมื่อพิมพ์ข้อความใน lineEdit ก็จะเกิดการเปลี่ยนแปลง (textChanged) ซึ่งจะถูกส่งไปกำหนดค่าใน lineEdit_4 ผ่าน slot ชื่อ setText เราจึงเห็นข้อความใน lineEdit_4 เปลี่ยนตามข้อความที่พิมพ์ (รวมไปถึง lineEdit_2, lineEdit_3 และ TextLabel ด้วย)
โดยหลักการของ Signal และ Slot ก็มีเพียงเท่านี้ ลองทำความเข้าใจดีๆ จะเห็นว่าไม่ยากและมีความยืดหยุ่นคล่องตัวมากเลยทีเดียว
ไม่มีความคิดเห็น:
แสดงความคิดเห็น