Привіт усім.
В даній статті розповідається про планетарно відомий кросплатформенний фереймворк графічних інтерфейсів для користувачів віконних програм- Qt. Основна мова програмування на якій і під яку розроблявся Qt - це C++. Але існують бібліотеки-адаптори для інших мов програмування на подобі Java, Python, C#, Node.js, PHP, Ruby і інші.
З-поміж усього іншого, візуальний фреймворк Qt відомий своїм використанням у GNU/Linux ОС-дистрибутивах на базі віконної системи KDE. Віконна система KDE, реалізована з використанням фреймворку Qt, надає користувачу повне функціональне віконне середовище для роботи і відпочинку з великою кількістю програм таких як Веб-браузери, офісні пакети і багато іншого.
Документація і домашня сторінка фреймворку
Сайт координаторів і розробників Qt знаходиться за адресою https://www.qt.io/. На ньому можна знайти документацію по Qt а також іншим розробкам компанії.
Історію створення фреймворку можна прочитати на Вікіпедії за адресою https://uk.wikipedia.org/wiki/Qt.
Деталі і вступ про Qt можна знайти на сторінці офіційної документації https://doc.qt.io/qt-6/qt-intro.html.
Дзеркало репозиторіїв на GitHub розміщено за адресою https://github.com/qt. Саме Qt 5 версії знаходиться за адресою https://github.com/qt/qt5.
Способи розробки
Qt підтримує декілька типів створення і збирання програм з вихідного джерельного коду. А саме:
- Створення і збирання програм за допомогою QtCreator - IDE від розробників Qt.
- Створення програми за допомогою QML і Qt Quick;
- Компіляція проекту за допомогою qmake;
- Компіляція проекту за допомогою інших засобів на подобі cmake і стандартного make.
У даній статті ми будемо використовувати стандартні засоби збирання проектів - cmake і звичайний make разом з Makefile-ами.
Віджети візуальної системи
На сайті документації по візульній системі Qt розміщено майже 200 класів для візуальної системи. Їх можна переглянути за посиланням https://doc.qt.io/qt-6/qtwidgets-module.html.
Онсовні віджети для створення вікон являються QApplication для запуску циклу обробки подій і QMainWindow для відображення головного вікна програми. Приклади використання будуть розміщені у секції прикладів.
Основними віджетами які вставляються у примірник класу QMainWindow головного вікна програми можуть бути:
- QLineEdit для введення і відображення інформації.
- QLabel для відображення текстової і графічної інформації на вікні.
- QPushButton для створення командних кнопок для виконання певних дій.
- QRadioButton для створення прапорців для вибору єдиного з множини.
- QCheckBox для створення прапорців опцій
- QMenuBar, QMenu і QAction - використовуються для побудови головного меню програми, розміщеного у верхній частині вікна.
- QTextEdit віджет для введення, редагування і відображення багаторядкової текстової інформації.
- QFileDialog доволяє користувачу обрати файл на доступних носіях.
- QInputDialog довзоляє користувачу ввести певну інформацію по запиту програми.
- QMessageBox віджет дозволяє створювати модальні діалогові вікна для інформування користувача.
- QStatusBar, який використовується для відображення статусу у нижній частині вікна програми (разом з QLabel). І багато інших.
На сторінках офіційної документації до відповідних класів можна знайти список підтримуваних методів і детальну інформацію до них.
За допомогою Qt також можна писати кросплатформенні програми без відображення вікон.
Приклади
Хоча у прикладах використовуються дві системи побудови для наглядності - CMake і Unix Makefile-ли, у випадку не Unix-подібної системи краще використовувати саме CMake систему. Оскільки CMake являється кросплатформенною системою генерації скриптів побудови, більш ймовірно що проект буде успішно зібрано у системі яка використовується.
Приклад #1 - як показати вікно
Розглянемо простий приклад використання QApplication і QMainWindow для показу пустого вікна на екран користувача. Даний приклад можна використовувати як базу для створення довільних вікон. Тому код з даного прикладу буде використовуватись і для інших прикладів.
Репозиторій з усіма файлами
Усі файли проекту можна переглянути за посиланням https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main/basic-window, що знаходиться у GitHub репозиторію проекту-демонстрації для даної статті за посиланням https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main. Увесь код проекту можна завантажити за допомогою команди git:
# якщо git ще не встановлено у системі sudo apt-get install -y git git clone https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources.git
Клас ArbitraryWindow
Спочатку необхідно оголосити головний клас вікна, який являє собою дочірній від того самого QMainWindow. Назвемо цей клас ArbitraryWindow. В загальному його оголошення може виглядати наступним чином:
#ifndef ARBITRARYWINDOW_H #define ARBITRARYWINDOW_H // підключаємо оголошення класу QMainWindow #include <QMainWindow> /* * Створюємо клас довільного вікна ArbitraryWindow * для відображення на екрані. */ class ArbitraryWindow: // обов'язково потрібно вказати клас QMainWindow // у якості батьківського класу public QMainWindow { // обов'язковий виклик макросу! Q_OBJECT public: ArbitraryWindow(); private slots: private: }; #endif //ARBITRARYWINDOW_H
Необхідно звернути увагу на обов'язковий макрос Q_OBJECT який використано всередині тіла оголошення класу QMainWindow. Без даного макросу вікно може не реагувати на події користувача.
Визначення класу, в даному випадку, - тривіальне, тому не будемо на ньому зупинятись.
Головна функція C++ програми
Далі можна поглянути на головну функцію програми - main. Вона може виглядати наступним чином:
#include <QApplication> #include "ArbitraryWindow.h" // головна функція C++ програми int main (int argc, char** argv) { // створюємо обробник подій QApplication eventLoop(argc, argv); // створюємо примірник головного вікна ArbitraryWindow justAWindow; // показуємо вікно на екран justAWindow.show(); //запускаємо цикл обробки подій вікон return eventLoop.exec(); }
Даний файл розміщений за посиланням https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/basic-window/main.cpp.
Компіляція або збирання проекту
Даний проект можна скомпілювати декількома способами, а саме за допомогою системи генерації скриптів побудови CMake, або самою програмою побудови make.
Збирання за допомогою CMake
Щоб зібрати даний проект необхідно виконати наступні команди у командному рядку Linux, або будь-якої іншої підтримуваної ОС:
mkdir -vp build cd build cmake ../ cmake --build .
Вивід може виглядати наступним чином:
Збирання за допомогою Makefile
Скрипт Makefile який спроможний зібрати просте вікно на Qt5, може виглядати наступним чином:
CXXFLAGS=-g -Wall -Werror \ -I build/ -I window/ \ `pkg-config --cflags Qt5Widgets` \ `pkg-config --cflags Qt5Core` QTLIBS=`pkg-config --libs Qt5Widgets` \ `pkg-config --libs Qt5Core` debug: mkdir -vp build moc window/ArbitraryWindow.h -o build/ArbitraryWindow.moc.h c++ -c -fPIC $(CXXFLAGS) window/ArbitraryWindow.cpp -o build/ArbitraryWindow.cpp.o c++ -c -fPIC $(CXXFLAGS) main.cpp -o build/main.cpp.o c++ -o build/Qt5BasicMainWindow build/main.cpp.o build/ArbitraryWindow.cpp.o $(QTLIBS) clean: rm -fr build rm -f *.o
Даний скрипт розміщено за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/basic-window/Makefile.
І щоб скомпілювати демо-вікно за допомогою даного Makefile-скрипта необхідно скористатись наступними командами для командного інтерпретатора Linux чи іншої Unix-подібної ОС (вводити з кореня проекту):
cd basic-window/ make clean debug
Вивід може виглядати наступним чином:
Фінальний результат
Після компіляції обома способами і запуску програми на екрані можна побачити наступне вікно:
Приклад #2 - вікно з меню
Розглянемо приклад не складного вікна з меню, яке показує модальне діалогове вікно при натисканні на один елемент субменю.
Усі файди прикладу можна знайти у директорії за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main/window-with-menu GitHub репозиторію, що знаходиться за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main.
Оголошення і визначення класу WindowWithMenu
Спочатку оголошуємо клас WindowWithMenu, який являється дочірнім від QMainWindow. Повний приклад оголошення можна знайти за посиланням https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/window-with-menu/window/WindowWithMenu.h з репозиторію прикладів для даної статті за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main.
// підключаємо оголошення класу QMainWindow #include <QMainWindow> /* * Створюємо клас вікна з меню WindowWithMenu * для відображення на екрані. */ class WindowWithMenu: // обов'язково потрібно вказати клас QMainWindow // у якості батьківського класу public QMainWindow { // обов'язковий виклик макросу! Q_OBJECT public: // конструктор у якому створюється меню WindowWithMenu(); private slots: // метод-слот для меню "Сказати привіт" void sayHello(); private: };
Після чого можна визначити конструктор класу WindowWithMenu, який буде створювати і упаковувати об'єкти меню, а також метод sayHello, котрий показуватиме модальне інформаційне вікно з текстом, використовуючи клас-віджет QMessageBox. Повний приклад реалізації методів можна переглянути за посиланням https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/window-with-menu/window/WindowWithMenu.cpp. Реалізація може виглядати наступним чином:
#include <QMenuBar> #include <QMenu> #include <QAction> #include <QMessageBox> WindowWithMenu::WindowWithMenu() { // створюємо меню "Програма" на панелі меню auto fileMenu = menuBar()->addMenu(tr("Програма")); // свтрюємо елемент субменю "Сказати привіт" auto hello = fileMenu->addAction(tr("Сказати привіт")); // поєднюємо меню з конкретним методом-слотом // класу sayHello connect(hello, SIGNAL(triggered()), this, SLOT(sayHello())); } void WindowWithMenu :: sayHello() { // код, який показує віконечко з привітом ;) QMessageBox::information( this, tr("Привіт"), tr("Привіт, Планета!") ); }
Як видно з коду, в реалізації класу присутні два методи - конструктор і sayHello. У самому конструкторі виконуються побудова дерева меню вікна за допомогою методів addMenu (для елементів які розкриваються з панеллю) чи addAction (для самих елементів меню, які виконують певні дії). У нашому випадку слот-метод sayHello викликає статичний метод з класу QMessageBox для показу інформаційного вікна з привітанням.
Головна функція програми виглядає так само як і в попередньому прикладі, за виключенням використаного файлу підключення і класу створеного примірника вікна. Детальніше можна переглянути за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/window-with-menu/main.cpp.Побудова проекту класу WindowWithMenu - Qt5WindowWithMenu
Щоб побудувати проект для вікна з меню, небхідно склонувати його репозиторій на локальну машину за допомогою команд
# якщо git ще не встановлено у системі sudo apt-get install -y git git clone https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources.git
Наступним кроком буде використання CMake для побудови бінарного виконуваного файлу з вихідного джерельного коду за допомогою команд:
cd kytok.org.ua-Qt-intro-resources/ mkdir -vp build cd build cmake ../ cmake --build . --target Qt5WindowWithMenu
Вивід у командний рядок може виглядати наступним чином:
Як альтернативний спосіб побудови можна використати стандартну Unix-команду make разом з створеним файлом Makefile вміст якого можна переглянути за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/window-with-menu/Makefile. Команди командного рядка для побудови наступні (з кореню проекту https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main):
cd window-with-menu/ make clean debug
Вивід може виглядати наступним чином:
Результат успішної збірки і запуску програми буде приблизно наступний:
Після натискання на елемент меню:
Приклад #3 - вікно з кнопкою, полем для вводу і прапорцями
В даному прикладі розглянемо нескладне вікно з декількома елементами у ньому: поле для вводу імені QLineEdit або довільного тексту, QPushButton для ініціювання взаємодії і два взаємовиключаючі прапорця для вказування типу взаємодії.
Усі файди прикладу можна знайти у директорії за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main/button-with-hello GitHub репозиторію, що знаходиться за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/tree/main.
Оголошення і визначення класу HelloButtonWindow
Оголошення класу HelloButtonWindow може виглядати наступним чином:
// підключаємо оголошення класу QMainWindow // і інші необхідні класи #include <QMainWindow> #include <QRadioButton> #include <QLineEdit> /* * Створюємо клас вікна HelloButtonWindow * для відображення на екрані. */ class HelloButtonWindow: // обов'язково потрібно вказати клас QMainWindow // у якості батьківського класу public QMainWindow { // обов'язковий виклик макросу! Q_OBJECT public: HelloButtonWindow(); private slots: void interact(); private: QRadioButton* hello; QLineEdit* edit; };
Повний файл оголошення класу можна переглянутиз а адресою GitHub репозиторію https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/button-with-hello/window/HelloButtonWindow.h.
Після чого сама реалізація класу насутпна:
// підключаємо згенерований moc-програмою // заголовковий файл #include "HelloButtonWindow.moc.h" #include <QHBoxLayout< #include <QPushButton> #include <QLineEdit> #include <QFrame> #include <QRadioButton> #include <QMessageBox> HelloButtonWindow::HelloButtonWindow(): hello{nullptr}, edit{nullptr} { // будуємо вікно взаємодії auto frame = new QFrame ; setCentralWidget(frame); auto button = new QPushButton(tr("Взаємодія")); edit = new QLineEdit; auto form = new QHBoxLayout; auto bye = new QRadioButton(tr("попрощатись")); hello = new QRadioButton(tr("привітатись")); frame->setLayout(form); form->addWidget(edit); form->addWidget(button); form->addWidget(bye); form->addWidget(hello); connect(button, SIGNAL(clicked()), this, SLOT(interact())); hello->setChecked(true); setWindowTitle(tr("Вікно взаємодії")); } void HelloButtonWindow::interact() { //обчислюємо префікс взаємодії auto interactionText = hello->isChecked() ? tr("Привіт") : tr("До побачення") ; //отримуємо введений текст auto text = edit->displayText(); interactionText += ", " + text + "!"; if (text.isEmpty()) { // якщо відсутній текст - показати попередження QMessageBox::warning( this, tr("Помилка"), tr("Введіть ім'я!") ); return ; } // код, який показує віконечко з взаємодією ;) QMessageBox::information( this, tr("Взаємодія"), interactionText ); }
Повністю файл реалізації класу HelloButtonWindow можна переглянути за адресою https://github.com/yuriysydor1991/kytok.org.ua-Qt-intro-resources/blob/main/button-with-hello/window/HelloButtonWindow.cpp.
Побудова проекту
Щоб побудувати виконуваний файл для класу HelloButtonWindow за допомогою CMake, необхідно скористатись наступними командами (з кореня проекту):
mkdir -vp build cd build cmake ../ cmake --build . --target Qt5HelloButtonWindow
Що у командному рядку GNU/Linux заснованої ОС Linux Mint може виколядати наступним чином:
У якості альтернативи, для наглядності, можна скористатись стандартом для Unix-подібних систем Makefile-ом і командою make у командному рядку (з кореня поректу):
cd button-with-hello/ make clean debug
Запуск прикладу
Після успішної побудови і запуску виконуваного файлу даного прикладу, на екрані можна побачити наступне:
Після введення тексту у поле для вводу і натискання відповідної кнопки, можна побачити наступне:
Приклад текстового редактора
Приклад тривіального редактора текстових файлів реалізованого з використанням Qt5 C++ і CMake (також з іншими технологіями) можна переглянути за адресою GitHub репозиторію https://github.com/yuriysydor1991/Qt1SimpleTextEditor.
Офіційні приклади від розробників Qt
З-поміж усього іншого розробники Qt предоставляють власні приклади використання даної візуальної системи. Доступні приклади для різних версій фреймворку. Також присутні приклади не тільки для настільних комп'ютерів, а й також для інших платформ.
Для Qt версії 5.15 LTS вони доступні за адресою https://doc.qt.io/qt-5/qtexamplesandtutorials.html.
Для версії 6.6 LTS приклади доступні за адресою https://doc.qt.io/qt-6.5/qtexamplesandtutorials.html.