Привіт усім.

В даній статті розповідається про планетарно відомий кросплатформенний фереймворк графічних інтерфейсів для користувачів віконних програм- 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 .

Вивід може виглядати наступним чином:

/resources/uploads/img/CMake-intro-simple-Qt5-window-showup-example-build-output

Збирання за допомогою 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

Вивід може виглядати наступним чином:

/resources/uploads/img/Qt-intro-compaling-basic-window-code-with-a-Makefile-output-example.png

Фінальний результат

Після компіляції обома способами і запуску програми на екрані можна побачити наступне вікно:

/resources/uploads/img/Qt-intro-basic-window-compiled-example-output.png

Приклад #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

Вивід у командний рядок може виглядати наступним чином:

/resources/uploads/img/Qt-intro-window-with-menu-cmake-build-output-Qt5WindowWithMenu-example.png

Як альтернативний спосіб побудови можна використати стандартну 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

Вивід може виглядати наступним чином:

/resources/uploads/img/Qt-intro-building-window-with-menu-with-help-of-Makefile-output-example.png

Результат успішної збірки і запуску програми буде приблизно наступний:

/resources/uploads/img/Qt-intro-window-with-menu-example-window-showpng

Після натискання на елемент меню:

/resources/uploads/img/Qt-intro-window-with-menu-action-interaction-output-example.png

Приклад #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 може виколядати наступним чином:

/resources/uploads/img/Qt-intro-button-with-hello-examlpe-build-output-example.png

У якості альтернативи, для наглядності, можна скористатись стандартом для Unix-подібних систем Makefile-ом і командою make у командному рядку (з кореня поректу):

cd button-with-hello/
make clean debug

Запуск прикладу

Після успішної побудови і запуску виконуваного файлу даного прикладу, на екрані можна побачити наступне:

/resources/uploads/img/Qt-intro-button-with-hello-run-examplepng

Після введення тексту у поле для вводу і натискання відповідної кнопки, можна побачити наступне:

/resources/uploads/img/Qt-intro-button-with-hello-interaction-example.png

Приклад текстового редактора

Приклад тривіального редактора текстових файлів реалізованого з використанням Qt5 C++ і CMake (також з іншими технологіями) можна переглянути за адресою GitHub репозиторію https://github.com/yuriysydor1991/Qt1SimpleTextEditor.

/resources/uploads/img/Qt-intro-text-editor-demo-project-view.png

Офіційні приклади від розробників 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.

Категорії: