ตอนที่ 5: ทำความรู้จัก Basic Widgets (QPushButton, QLabel, QLineEdit)

1. 🎯 ตอนที่ 5: สร้างฟอร์มล็อกอินด้วย 3 ทหารเสือ Basic Widgets
2. 📖 เปิดฉาก (The Hook)
สวัสดีครับน้องๆ โปรแกรมเมอร์! กลับมาลุยกันต่อในซีรีส์ ลุยโปรเจกต์ Cross-Platform GUI ด้วย C++ และ Qt ครับ
ในตอนที่แล้วเราได้เรียนรู้วิธีการจัดหน้าจอ (Layout Management) กันไปแล้ว เปรียบเสมือนเราสร้างโครงสร้างและแบ่งห้องให้กับบ้านของเราได้สำเร็จ ทีนี้ก็ถึงเวลาเอา “เฟอร์นิเจอร์” เข้ามาตกแต่งในบ้านกันแล้วครับ!
เฟอร์นิเจอร์ในโลกของ Qt ก็คือสิ่งที่เราเรียกว่า Widget นั่นเองครับ ในอดีตการสร้างปุ่มสักปุ่มด้วย C++ บนระบบปฏิบัติการเพียวๆ เราต้องคำนวณการวาดสี่เหลี่ยม วาดเงา และดักจับการคลิกเมาส์เองทั้งหมด แต่โชคดีที่ Qt เตรียม Widget สำเร็จรูปมาให้เราใช้งานอย่างจุใจ โดยในบทนี้ พี่จะพาไปรู้จักกับ “3 ทหารเสือ” ที่เป็น Basic Widgets พื้นฐานที่สุดที่ทุกโปรแกรมต้องมี นั่นคือ QLabel, QLineEdit และ QPushButton พร้อมกับนำทั้งสามตัวนี้มาประกอบร่างกันเป็น “หน้าต่างล็อกอิน (Login Form)” แบบง่ายๆ กันครับ!
3. 🧠 แก่นวิชา (Core Concepts)
ในโลกของ Qt คลาสของ Widget ทุกตัวจะสืบทอดมาจากคลาสแม่ที่ชื่อว่า QWidget ทำให้มันมีคุณสมบัติพื้นฐานร่วมกัน เช่น การตั้งค่าขนาด สี หรือฟอนต์ แต่ 3 ทหารเสือที่เราจะพูดถึงวันนี้ มีหน้าที่เฉพาะตัวดังนี้ครับ:
QLabel(ป้ายข้อความ): ใช้สำหรับแสดงผลข้อความ (Text) หรือรูปภาพ (Image) บนหน้าจอแบบอ่านได้อย่างเดียว (Read-only) เปรียบเสมือนป้ายชื่อหน้าห้อง หรือข้อความบอกใบ้ว่าช่องนี้ต้องกรอกอะไรQLineEdit(ช่องกรอกข้อความบรรทัดเดียว): เป็นกล่องให้ผู้ใช้พิมพ์ข้อความสั้นๆ ลงไปได้ เช่น ชื่อผู้ใช้ หรือรหัสผ่าน สามารถจำกัดความยาวของตัวอักษรได้ด้วยฟังก์ชันsetMaxLength()QPushButton(ปุ่มกด): ปุ่มมาตรฐานสำหรับรับคำสั่งจากผู้ใช้ เมื่อผู้ใช้นำเมาส์ไปคลิก มันจะเปล่ง Signal ที่ชื่อว่าclicked()ออกมาให้เรานำไปผูกกับ Slot เพื่อสั่งงานโปรแกรมต่อไป
กระบวนท่าการดึงและกำหนดค่า: text() และ setText()
สิ่งที่น้องๆ ต้องใช้บ่อยที่สุดในการทำงานกับ Widget เหล่านี้คือการอ่านและเขียนข้อมูลครับ
- ถ้าต้องการ “ดึงค่า” ที่อยู่ในช่องกรอกข้อความ เราจะใช้ฟังก์ชัน
text()ซึ่งจะคืนค่ากลับมาเป็นออบเจกต์ของคลาสQString(คลาสจัดการสตริงที่ทรงพลังของ Qt) - ถ้าต้องการ “ตั้งค่า” หรือเขียนข้อความลงไปบนป้ายหรือปุ่ม เราจะใช้ฟังก์ชัน
setText(const QString &)เข้าไปแทนที่ครับ
ฟีเจอร์ลับสำหรับรหัสผ่าน:
ในการทำฟอร์มล็อกอิน หากผู้ใช้พิมพ์รหัสผ่าน เราคงไม่อยากให้คนข้างๆ เห็นใช่ไหมครับ? QLineEdit มีไม้ตายที่เรียกว่า setEchoMode() โดยเราสามารถส่งพารามิเตอร์ QLineEdit::Password เข้าไป เพื่อเปลี่ยนตัวอักษรที่พิมพ์ให้กลายเป็นจุดสีดำหรือดอกจัน (Dot/Asterisk) ได้อัตโนมัติครับ

4. 💻 ร่ายมนต์โค้ด (Show me the Code)
เรามาดูตัวอย่างการประกอบร่าง 3 ทหารเสือให้กลายเป็น Login Form กันครับ ในตัวอย่างนี้พี่จะจำลองว่าเราออกแบบหน้าจอผ่าน Qt Designer และสร้างปุ่ม Login ไว้เรียบร้อยแล้ว จากนั้นเราจะมาเขียนลอจิก C++ เพื่อดักจับ Event การคลิกกันครับ
#include "logindlg.h"
#include "ui_logindlg.h"
#include <QMessageBox> // สำหรับแสดงหน้าต่างแจ้งเตือน
#include <QDebug>
// ... [โค้ดส่วน Constructor] ...
// สล็อต (Slot) ที่จะทำงานเมื่อปุ่มถูกคลิก
void loginDlg::on_loginBtn_clicked()
{
// 1. ใช้ฟังก์ชัน text() ดึงค่าจาก QLineEdit มาเก็บไว้ใน QString
// เคล็ดลับ: ใช้ trimmed() เพื่อตัดช่องว่าง (Space) ที่ผู้ใช้อาจเผลอพิมพ์ติดมาที่หัวหรือท้ายข้อความ
QString username = ui->usrLineEdit->text().trimmed();
QString password = ui->pwdLineEdit->text();
qDebug() << "กำลังตรวจสอบผู้ใช้:" << username;
// 2. ตรวจสอบเงื่อนไข Username และ Password (ในของจริงมักจะเช็กกับ Database)
if (username == "admin" && password == "123456")
{
// ถ้าถูกต้อง ให้เรียกฟังก์ชัน accept() เพื่อปิดหน้าต่างและส่งสัญญาณว่าล็อกอินสำเร็จ
accept();
}
else
{
// ถ้าผิดพลาด ให้แสดงหน้าต่างแจ้งเตือน (QMessageBox)
QMessageBox::warning(this, "Warning", "User name or password error!", QMessageBox::Yes);
// 3. ใช้เคล็ดลับ UX: ล้างช่องข้อมูลและเด้งเคอร์เซอร์กลับไปที่ช่อง Username
ui->usrLineEdit->clear(); // หรือใช้ ui->usrLineEdit->setText(""); ก็ได้
ui->pwdLineEdit->clear();
ui->usrLineEdit->setFocus();
}
}(อ้างอิงโค้ดลอจิกจาก)
5. 🛡️ เคล็ดลับจากคัมภีร์ลับ (Under the Hood / Pro-Tips)
ในฐานะ Senior พี่ขอหยิบข้อควรระวังและเคล็ดลับที่มักจะเจอบ่อยในหน้างานจริงมาฝากครับ:
- พลังของ
trimmed(): น้องๆ สังเกตไหมครับว่าในโค้ดพี่ใช้ui->usrLineEdit->text().trimmed()เสมอเมื่อรับค่า Username เพราะบ่อยครั้งที่ผู้ใช้ก็อปปี้ชื่อมาวางแล้วมี “ช่องว่าง” (Whitespace) ติดมาด้วย หากเราเอาไปเทียบกับค่าในระบบตรงๆ มันจะแจ้งว่ารหัสผิดทันที การใช้trimmed()จะช่วยตัดช่องว่างหัวท้ายทิ้งให้โดยอัตโนมัติครับ - จัดการหน่วยความจำผ่าน Parent-Child: เมื่อน้องๆ ใช้คำสั่ง
new QPushButton(this);ตัวแปรthisที่โยนเข้าไปใน Constructor จะเป็นการบอกว่าหน้าต่างนี้คือ “แม่ (Parent)” ดังนั้นเมื่อหน้าต่างถูกปิดและถูกลบออกจากหน่วยความจำ Qt จะทำการกวาดล้าง Widget ลูกๆ ทั้งหมดให้เองโดยอัตโนมัติ ไม่ต้องมานั่งเขียนdeleteเองให้เสี่ยงต่ออาการ Memory Leak ครับ! - การตั้ง Tab Order: สิ่งหนึ่งที่โปรแกรมเมอร์มือใหม่มักมองข้ามคือ User Experience (UX) ครับ เวลาผู้ใช้พิมพ์ Username เสร็จ เขามักจะกดปุ่ม
Tabบนคีย์บอร์ดเพื่อเลื่อนเคอร์เซอร์ไปช่อง Password ทันที ใน Qt Designer น้องๆ สามารถกดโหมด Edit Tab Order เพื่อตั้งลำดับการโฟกัสของ Widget ให้เรียงจากบนลงล่างได้อย่างถูกต้อง
6. 🏁 บทสรุป (To be continued…)
เป็นอย่างไรบ้างครับกับ 3 ทหารเสือ QLabel, QLineEdit และ QPushButton เพียงแค่เรานำ Widget พื้นฐานเหล่านี้มาประกอบกัน และใช้คำสั่ง text(), setText() ร่วมกับกลไก Signals & Slots เราก็สามารถสร้างแอปพลิเคชันที่มีการโต้ตอบกับผู้ใช้แบบเบื้องต้นได้แล้วครับ
แต่เดี๋ยวก่อน! แอปพลิเคชันในโลกความเป็นจริงไม่ได้มีแค่ปุ่มหรือช่องกรอกข้อความเท่านั้น ในตอนต่อไป พี่จะพาไปรู้จักกับ Widget ระดับที่ซับซ้อนขึ้นอย่าง QComboBox (รายการแบบดรอปดาวน์) และ QCheckBox (กล่องทำเครื่องหมาย) ที่จะช่วยให้โปรแกรมของเรารับข้อมูลทางเลือกจากผู้ใช้ได้แม่นยำขึ้น ติดตามกันให้ดีนะครับ!
ต้องการที่ปรึกษาด้านการออกแบบสถาปัตยกรรมซอฟต์แวร์ C++ หรือระบบ Cross-Platform GUI ให้กับองค์กรของคุณ? ทีมงาน WP Solution พร้อมให้บริการออกแบบและพัฒนาซอฟต์แวร์แบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p