เวลาเราดำเนินการอะไรจากออบเจ็กต์หนึ่งแล้วย่อมต้องการผลจากการกระทำนั้นไปปรากฏยังออบเจ็กต์หนึ่ง (ไม่งั้นจะทำไปทำไม ใช่ไหมครับ) เช่น เราคลิกปุ่มที่กำหนดเป็นปุ่ม 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 ก็มีเพียงเท่านี้ ลองทำความเข้าใจดีๆ จะเห็นว่าไม่ยากและมีความยืดหยุ่นคล่องตัวมากเลยทีเดียว
ไม่มีความคิดเห็น:
แสดงความคิดเห็น