Trong quá trình phát triển ứng dụng với Qt, việc tạo giao diện hoàn toàn bằng code mang lại nhiều lợi thế như kiểm soát chi tiết từng thành phần và dễ dàng tùy biến logic. Bài viết này sẽ hướng dẫn chi tiết cách xây dựng UI bằng code thay vì sử dụng Qt Designer.
Bước 1: Tạo project và cấu hình
Khi tạo project mới, bỏ chọn tùy chọn Generate Form. Điều này đảm bảo Qt Creator không tự động sinh file .ui, giúp bạn tự tay viết toàn bộ code giao diện.
Bước 2: Khai báo các control trong header
Trong file dialog.h, khai báo tất cả các widget cần dùng và các hàm khởi tạo:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QCheckBox>
#include <QRadioButton>
#include <QPushButton>
#include <QPlainTextEdit>
#include <QFont>
#include <QPalette>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
private:
// Các widget chính
QCheckBox *checkUnderline;
QCheckBox *checkItalic;
QCheckBox *checkBold;
QRadioButton *radioBlack;
QRadioButton *radioBlue;
QRadioButton *radioRed;
QPlainTextEdit *textArea;
QPushButton *btnAccept;
QPushButton *btnReject;
QPushButton *btnQuit;
// Hàm tạo UI và kết nối tín hiệu
void constructUI();
void connectSignals();
private slots:
void toggleUnderline(bool state);
void toggleItalic(bool state);
void toggleBold(bool state);
void updateTextColor();
};
#endif
Bước 3: Xây dựng các control trong implementation
Trong file dialog.cpp, viết logic cho hàm constructUI():
#include "dialog.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
void Dialog::constructUI()
{
// Tạo checkbox
checkUnderline = new QCheckBox(tr("Gạch chân"));
checkItalic = new QCheckBox(tr("Nghiêng"));
checkBold = new QCheckBox(tr("Đậm"));
QHBoxLayout *firstRow = new QHBoxLayout;
firstRow->addWidget(checkUnderline);
firstRow->addWidget(checkItalic);
firstRow->addWidget(checkBold);
// Tạo radio button
radioBlack = new QRadioButton(tr("Đen"));
radioBlue = new QRadioButton(tr("Xanh"));
radioRed = new QRadioButton(tr("Đỏ"));
radioBlack->setChecked(true);
QHBoxLayout *secondRow = new QHBoxLayout;
secondRow->addWidget(radioBlack);
secondRow->addWidget(radioBlue);
secondRow->addWidget(radioRed);
// Tạo text editor
textArea = new QPlainTextEdit;
QFont baseFont = textArea->font();
baseFont.setPointSize(20);
textArea->setFont(baseFont);
textArea->setPlainText("Xin chào!\nĐây là văn bản mẫu.");
// Tạo nút bấm
btnAccept = new QPushButton(tr("Đồng ý"));
btnReject = new QPushButton(tr("Hủy bỏ"));
btnQuit = new QPushButton(tr("Thoát"));
QHBoxLayout *thirdRow = new QHBoxLayout;
thirdRow->addStretch();
thirdRow->addWidget(btnAccept);
thirdRow->addWidget(btnReject);
thirdRow->addStretch();
thirdRow->addWidget(btnQuit);
// Layout chính
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(firstRow);
mainLayout->addLayout(secondRow);
mainLayout->addWidget(textArea);
mainLayout->addLayout(thirdRow);
setLayout(mainLayout);
}
Bước 4: Kết nối tín hiệu và slot
Hàm connectSignals() thiết lập tất cả kết nối cần thiết:
void Dialog::connectSignals()
{
// Nút chức năng
connect(btnAccept, &QPushButton::clicked, this, &QDialog::accept);
connect(btnReject, &QPushButton::clicked, this, &QDialog::reject);
connect(btnQuit, &QPushButton::clicked, this, &QDialog::close);
// Checkbox
connect(checkUnderline, &QCheckBox::clicked, this, &Dialog::toggleUnderline);
connect(checkItalic, &QCheckBox::clicked, this, &Dialog::toggleItalic);
connect(checkBold, &QCheckBox::clicked, this, &Dialog::toggleBold);
// Radio button
connect(radioBlack, &QRadioButton::clicked, this, &Dialog::updateTextColor);
connect(radioBlue, &QRadioButton::clicked, this, &Dialog::updateTextColor);
connect(radioRed, &QRadioButton::clicked, this, &Dialog::updateTextColor);
}
Bước 5: Định nghĩa các slot xử lý
Các hàm xử lý sự kiện định dạng chữ:
void Dialog::toggleUnderline(bool state)
{
QFont currentFont = textArea->font();
currentFont.setUnderline(state);
textArea->setFont(currentFont);
}
void Dialog::toggleItalic(bool state)
{
QFont currentFont = textArea->font();
currentFont.setItalic(state);
textArea->setFont(currentFont);
}
void Dialog::toggleBold(bool state)
{
QFont currentFont = textArea->font();
currentFont.setBold(state);
textArea->setFont(currentFont);
}
void Dialog::updateTextColor()
{
QPalette palette = textArea->palette();
if (radioBlack->isChecked())
palette.setColor(QPalette::Text, Qt::black);
else if (radioBlue->isChecked())
palette.setColor(QPalette::Text, Qt::blue);
else if (radioRed->isChecked())
palette.setColor(QPalette::Text, Qt::red);
textArea->setPalette(palette);
}
Bước 6: Hoàn thiện constructor và destructor
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
constructUI();
connectSignals();
}
Dialog::~Dialog()
{
// Qt tự động quản lý bộ nhớ widget con
}
Kết quả đạt được
Sau khi chạy chương trình, bạn sẽ thấy một cửa sổ với:
- Hàng checkbox: Gạch chân, Nghiêng, Đậm
- Hàng radio: Đen, Xanh, Đỏ (mặc định chọn Đen)
- Vùng text editor với font chữ lớn (20pt)
- Ba nút: Đồng ý, Hủy bỏ, Thoát (căn chỉnh hợp lý)
Tương tác với checkbox sẽ thay đổi style chữ trực tiếp, radio button thay đổi màu chữ, và các nút thực hiện chức năng tương ứng (đóng cửa sổ hoặc trả về kết quả).