Trong bài này chúng ta sẽ học về cách làm menu và toolbar trong một ứng dụng Qt 5.
Ví dụ
Đoạn code dưới đây sẽ hiển thị một menu đơn giản.
#pragma once #include <QMainWindow> #include <QApplication> class SimpleMenu : public QMainWindow { public: SimpleMenu(QWidget *parent = 0); };
#include "simplemenu.h" #include <QMenu> #include <QMenuBar> SimpleMenu::SimpleMenu(QWidget *parent) : QMainWindow(parent) { QAction *quit = new QAction("&Quit", this); QMenu *file; file = menuBar()->addMenu("&File"); file->addAction(quit); connect(quit, &QAction::triggered, qApp, QApplication::quit); }
Đoạn code trên sẽ tạo ra menu File. Một lớp muốn có menu thì lớp này phải kế thừa từ QMainWindow
.
QAction *quit = new QAction("&Quit", this);
Dòng code trên tạo một đối tượng QAction
. Một action là một lớp chuyên để thực hiện một lệnh nào đó. Lý do tại sao nên dùng action thì bạn để ý trong một ứng dụng GUI thông thường có rất nhiều cách để thi hành một công việc nào đó, chẳng hạn muốn thoát Qt Creator thì bạn có thể bấm vào dấu “X” trên góc phải của Qt Creator, hoặc vào menu File→Quit, hoặc bấm Ctrl+Q, tất cả ba cách trên đều làm chung một việc, nên tốt nhất là ta connect cả ba cách đó vào một action. Một QMenu
có thể có một hoặc nhiều action.
QMenu *file; file = menuBar()->addMenu("&File");
Tạo một đối tượng QMenu
.
file->addAction(quit);
Dùng phương thức addAction()
để thêm action.
connect(quit, &QAction::triggered, qApp, QApplication::quit);
Sau đó connect action này với phương thức quit()
của qApp
. Nếu chưa biết qApp
là gì thì bạn có thể tìm phần trước của bài này để đọc.
#include "simplemenu.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); SimpleMenu window; window.resize(250, 150); window.setWindowTitle("Simple menu"); window.show(); return app.exec(); }
Icon, shortcut, separator
Trong phần này chúng ta sẽ tùy biến menu bằng cách thêm icon, phím tắt (shortcut) và các dòng phân cách – separator.
#pragma once #include <QMainWindow> #include <QApplication> class AnotherMenu : public QMainWindow { public: AnotherMenu(QWidget *parent = 0); };
#include "anothermenu.h" #include <QMenu> #include <QMenuBar> AnotherMenu::AnotherMenu(QWidget *parent) : QMainWindow(parent) { QPixmap newpix("new.png"); QPixmap openpix("open.png"); QPixmap quitpix("quit.png"); QAction *newa = new QAction(newpix, "&New", this); QAction *open = new QAction(openpix, "&Open", this); QAction *quit = new QAction(quitpix, "&Quit", this); quit->setShortcut(tr("CTRL+Q")); QMenu *file; file = menuBar()->addMenu("&File"); file->addAction(newa); file->addAction(open); file->addSeparator(); file->addAction(quit); qApp->setAttribute(Qt::AA_DontShowIconsInMenus, false); connect(quit, &QAction::triggered, qApp, &QApplication::quit); }
Trong ví dụ này chúng ta tạo ra một menu với ba action, nhưng chỉ dùng tới action quit thôi. Ngoài ra ta sẽ thêm một dòng phân cách và phím tắt Ctrl+Q.
QPixmap newpix("new.png"); QPixmap openpix("open.png"); QPixmap quitpix("quit.png");
Đây là hình icon cho menu. Lưu ý có một số môi trường không cho phép hiển thị icon trên menu.
QAction *newa = new QAction(newpix, "&New", this); QAction *open = new QAction(openpix, "&Open", this); QAction *quit = new QAction(quitpix, "&Quit", this);
Đoạn code trên tạo QAction
với tham số đầu tiên là icon mà nó sẽ dùng.
quit->setShortcut(tr("CTRL+Q"));
Tạo phím tắt, cứ mỗi lần bấm tổ hợp đúng tổ hợp phím thì chương trình sẽ thoát.
file->addSeparator();
Thêm dòng phân cách. Dòng phân cách chẳng qua chỉ là một đường kẻ ngang để gộp nhóm một số action có chung đặc điểm lại với nhau.
qApp->setAttribute(Qt::AA_DontShowIconsInMenus, false);
Như đã nói ở trên, trong một số môi trường icon sẽ không được hiển thị, nhưng chúng ta có thể bắt nó hiển thị bằng cách đưa thuộc tính Qt::AA_DontShowIconsInMenus
thành false.
#include "anothermenu.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); AnotherMenu window; window.resize(350, 200); window.setWindowTitle("Simple menu"); window.show(); return app.exec(); }
File main.
Check menu
Ví dụ dưới đây sẽ tạo ra menu có thể check được. Chúng ta sẽ tạo ra một thanh trạng thái (statusbar), cứ mỗi lần check hoặc bỏ check menu này thì statusbar sẽ hiện hoặc ẩn.
#pragma once #include <QMainWindow> #include <QApplication> class Checkable : public QMainWindow { Q_OBJECT public: Checkable(QWidget *parent = 0); private slots: void toggleStatusbar(); private: QAction *viewst; };
#include "checkable.h" #include <QMenu> #include <QMenuBar> #include <QStatusBar> Checkable::Checkable(QWidget *parent) : QMainWindow(parent) { viewst = new QAction("&View statusbar", this); viewst->setCheckable(true); viewst->setChecked(true); QMenu *file; file = menuBar()->addMenu("&File"); file->addAction(viewst); statusBar(); connect(viewst, &QAction::triggered, this, &Checkable::toggleStatusbar); } void Checkable::toggleStatusbar() { if (viewst->isChecked()) { statusBar()->show(); } else { statusBar()->hide(); } }
Check menu sẽ làm ẩn hoặc hiện statusbar.
viewst = new QAction("&View statusbar", this); viewst->setCheckable(true); viewst->setChecked(true);
Phương thức setCheckable()
để chuyển menu thành dạng có thể check được. Rồi dùng phương thức setChecked()
để làm cho menu đó đã check rồi nếu thích.
if (viewst->isChecked()) statusBar()->show(); else statusBar()->hide();
Phương thức toggleStatusbar()
sẽ làm cho thanh statusbar ẩn hoặc hiện.
#include "checkable.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Checkable window; window.resize(250, 150); window.setWindowTitle("Checkable menu"); window.show(); return app.exec(); }
QToolBar
Lớp QToolBar
sẽ hiển thị một thanh ngang chứa các nút lệnh cho ứng dụng, ngoài ra bạn có thể dùng chuột kéo thanh này sang trái, phải hoặc nằm dưới.
#pragma once #include <QMainWindow> #include <QApplication> class Toolbar : public QMainWindow { Q_OBJECT public: Toolbar(QWidget *parent = 0); };
#include "toolbar.h" #include <QToolBar> #include <QIcon> #include <QAction> Toolbar::Toolbar(QWidget *parent) : QMainWindow(parent) { QPixmap newpix("new.png"); QPixmap openpix("open.png"); QPixmap quitpix("quit.png"); QToolBar *toolbar = addToolBar("main toolbar"); toolbar->addAction(QIcon(newpix), "New File"); toolbar->addAction(QIcon(openpix), "Open File"); toolbar->addSeparator(); QAction *quit = toolbar->addAction(QIcon(quitpix), "Quit Application"); connect(quit, &QAction::triggered, qApp, &QApplication::quit); }
Lưu ý là luôn phải kế thừa từ lớp QMainWindow
nếu muốn tạo menu hoặc toolbar.
QToolBar *toolbar = addToolBar("main toolbar");
Phương thức addToolBar()
sẽ tạo một toolbar.
toolbar->addAction(QIcon(newpix), "New File"); toolbar->addAction(QIcon(openpix), "Open File"); toolbar->addSeparator();
Tạo hai action và một separator.
#include "toolbar.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Toolbar window; window.resize(300, 200); window.setWindowTitle("QToolBar"); window.show(); return app.exec(); }
Khung chương trình mẫu
Để kết thúc bài này, chúng ta sẽ tạo ra một khung chương trình mẫu.
#pragma once #include <QMainWindow> #include <QApplication> class Skeleton : public QMainWindow { Q_OBJECT public: Skeleton(QWidget *parent = 0); };
#include <QMenu> #include <QMenuBar> #include <QStatusBar> #include <QTextEdit> #include <QToolBar> Skeleton::Skeleton(QWidget *parent) : QMainWindow(parent) { QPixmap newpix("new.png"); QPixmap openpix("open.png"); QPixmap quitpix("quit.png"); QAction *quit = new QAction("&Quit", this); QMenu *file; file = menuBar()->addMenu("&File"); file->addAction(quit); connect(quit, &QAction::triggered, qApp, &QApplication::quit); QToolBar *toolbar = addToolBar("main toolbar"); toolbar->addAction(QIcon(newpix), "New File"); toolbar->addAction(QIcon(openpix), "Open File"); toolbar->addSeparator(); QAction *quit2 = toolbar->addAction(QIcon(quitpix), "Quit Application"); connect(quit2, &QAction::triggered, qApp, &QApplication::quit); QTextEdit *edit = new QTextEdit(this); setCentralWidget(edit); statusBar()->showMessage("Ready"); }
Trong ví dụ này chúng ta tạo cả toolbar và statusbar.
QTextEdit *edit = new QTextEdit(this); setCentralWidget(edit);
Tạo một đối tượng QTextEdit
và đặt nó ngay giữa QMainWindow
.
#include "skeleton.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Skeleton window; window.resize(350, 250); window.setWindowTitle("Application skeleton"); window.show(); return app.exec(); }