Qt — это кроссплатформенный фреймворк на C++ для приложений с графическим интерфейсом (GUI) и не только: в нем есть модули для сети, работы с файлами, потоков, баз данных и мультимедиа. Один и тот же исходный код собирается под Windows, Linux и macOS, а с дополнительными сборками — под Android, iOS и встраиваемые системы.
Содержание
Ключевое отличие Qt от «просто библиотеки классов» — собственная объектная система поверх C++: базовый класс QObject, механизм сигналов и слотов и метаобъектный компилятор moc. Ниже разберем, как это устроено, чем виджеты отличаются от QML, как собрать проект и что важно знать про лицензию Qt 6.
Что такое Qt и что в него входит
Qt существует с середины 1990-х и вырос из библиотеки для GUI в большой набор модулей. На нем построена рабочая среда KDE Plasma, десктоп-клиент Telegram, продукты Autodesk и множество встраиваемых интерфейсов.
Различать стоит две вещи. Qt как библиотека — это классы C++ (QString, QWidget, QNetworkAccessManager и другие). Qt как SDK — это библиотека плюс инструменты вокруг нее:
- Qt Creator — IDE для разработки, отладки и профилирования; работает на Windows, Linux и macOS.
- Qt Designer — визуальный редактор форм для виджетов; раскладку сохраняет в
.ui(XML). - Qt Linguist — инструмент локализации приложений на разные языки.
- qmake и поддержка CMake — системы сборки проекта.
Для других языков есть привязки к библиотеке Qt: для Python это PyQt и PySide (официальная привязка от разработчиков Qt). Привязки для Ruby, Java и PHP исторически существовали, но давно почти не поддерживаются, поэтому для продакшена ориентироваться на них не стоит.
Объектная система: QObject и moc
Многие возможности Qt держатся на классе QObject. Если ваш класс наследует QObject и в теле стоит макрос Q_OBJECT, класс получает метаинформацию: имена методов, свойства, сигналы и слоты, доступные во время выполнения.
Эту метаинформацию генерирует не компилятор C++, а отдельный шаг сборки — moc (Meta-Object Compiler, метаобъектный компилятор). Он читает заголовки с макросом Q_OBJECT, находит signals: и slots: и генерирует дополнительный .cpp-файл, который собирается вместе с проектом. Поэтому сигналы и слоты — это не std::function и не шаблоны стандартной библиотеки, а расширение, встроенное через кодогенерацию.
#include <QObject>
class Counter : public QObject
{
Q_OBJECT // включаем метаобъектную систему: код добавит moc
public:
int value() const { return m_value; }
public slots:
void setValue(int v); // слот - обычный метод, вызывается по сигналу
signals:
void valueChanged(int newValue); // объявляем, тело генерирует moc
private:
int m_value = 0;
};
Слот — это обычный метод: у него есть тело, его можно вызвать напрямую. Сигнал — только объявление; его реализацию дописывает moc, а наш код лишь «испускает» сигнал через emit:
void Counter::setValue(int v)
{
if (v == m_value)
return;
m_value = v;
emit valueChanged(m_value); // уведомляем всех подключенных слушателей
}
Сигналы и слоты: как связать объекты
Сигналы и слоты — это способ развязать объекты: отправитель сигнала не знает, кто его слушает. Связь задается функцией QObject::connect. В Qt 5 и Qt 6 рекомендуется синтаксис с указателями на методы — его проверяет компилятор:
Counter a, b;
QObject::connect(&a, &Counter::valueChanged,
&b, &Counter::setValue);
a.setValue(10);
// a испускает valueChanged(10) -> вызывается b.setValue(10)
// теперь b.value() == 10
Старый строковый синтаксис SIGNAL(...)/SLOT(...) тоже работает, но ошибки в именах он ловит только во время выполнения, поэтому для нового кода его не берут. Один сигнал можно соединить с несколькими слотами и наоборот — это удобно для реакции на события интерфейса.
Минимальное приложение на виджетах
Теперь соберем самое маленькое рабочее GUI-приложение на модуле Qt Widgets. Его можно скопировать целиком:
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv); // создаем приложение и цикл событий
QPushButton button("Нажми меня");
button.resize(200, 60);
button.show();
// сигнал clicked кнопки соединяем со слотом quit приложения
QObject::connect(&button, &QPushButton::clicked,
&app, &QApplication::quit);
return app.exec(); // запускаем цикл обработки событий
}
Что произойдет: откроется окно с кнопкой «Нажми меня», нажатие на кнопку испускает сигнал clicked, тот вызывает слот quit, и приложение завершается. Ключевой момент — app.exec(): он запускает цикл событий, который слушает мышь, клавиатуру и таймеры. Без него окно мелькнет и сразу закроется.
Виджеты против QML: два способа делать интерфейс
В Qt два разных подхода к интерфейсу, и их важно не путать.
Qt Widgets — классический набор готовых элементов (QPushButton, QLineEdit, QTableView), описываемых на C++ или в Qt Designer. Хорошо подходит для десктопных приложений в стиле операционной системы: формы, таблицы, меню.
Qt Quick — более новый стек для гибких, анимированных интерфейсов. Разметку в нем пишут не на C++, а на декларативном языке QML с вкраплениями JavaScript для логики. Часто применяется в мобильных и встраиваемых интерфейсах, где нужны плавные анимации и нестандартный вид.
| Признак | Qt Widgets | Qt Quick / QML |
|---|---|---|
| Язык интерфейса | C++ (или Qt Designer) | QML + JavaScript |
| Стиль | нативный вид ОС | кастомный, анимированный |
| Типичная область | десктоп, формы, таблицы | мобильные, встраиваемые, авто |
| Логика | C++ | C++ через регистрацию типов |
Оба подхода могут работать в одном приложении: тяжелую логику пишут на C++, а интерфейс — на QML или виджетах. Выбор простой: нужен строгий десктоп в стиле системы — берут виджеты; нужен гибкий или мобильный интерфейс — берут Qt Quick.
Сборка проекта: qmake и CMake
Исторически Qt-проекты собирались через qmake и файл .pro. В Qt 6 основной и рекомендуемой системой сборки стал CMake — он лучше интегрируется со сторонними библиотеками и современными тулчейнами. qmake по-прежнему поддерживается для существующих проектов, но новые обычно начинают на CMake.
cmake_minimum_required(VERSION 3.16)
project(hello LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup() # включает автозапуск moc и др.
qt_add_executable(hello main.cpp)
target_link_libraries(hello PRIVATE Qt6::Widgets)
Функция qt_standard_project_setup() автоматически подключает запуск moc, uic (обработка .ui) и rcc (ресурсы), поэтому вручную вызывать метаобъектный компилятор не нужно.
Лицензирование Qt 6
Qt распространяется под несколькими лицензиями сразу, и это влияет на то, как его можно применять в коммерческом продукте:
- LGPLv3 — открытая лицензия; позволяет использовать Qt в закрытом приложении при выполнении условий (в первую очередь — динамическая линковка библиотек и возможность их замены пользователем).
- GPLv3 — открытая лицензия с требованием открывать исходный код производного продукта.
- Коммерческая — платная лицензия без обязательств открывать код; включает часть модулей и инструментов, недоступных в открытой версии.
Практический вывод: для проприетарного приложения обычно выбирают LGPL с динамической линковкой либо коммерческую лицензию. Состав модулей меняется между версиями, поэтому условия сверяют с текущим текстом лицензии Qt.
Выводы
- Qt — кроссплатформенный C++ фреймворк: один исходник собирается под настольные, мобильные и встраиваемые платформы, и это не только GUI, но и сеть, потоки, БД, мультимедиа.
- Основа Qt — класс
QObject, макросQ_OBJECTи метаобъектный компиляторmoc; сигналы и слоты реализованы через кодогенерацию, а не черезstd::function. - Сигналы и слоты развязывают объекты:
QObject::connectс указателями на методы — предпочтительный синтаксис в Qt 5 и Qt 6. - Виджеты и QML — два разных стека: виджеты для нативного десктопа на C++, Qt Quick/QML для гибких и мобильных интерфейсов.
- В Qt 6 основная система сборки — CMake; лицензирование тройное (LGPL/GPL/коммерческая), условия зависят от способа линковки и модулей.
Где применяется / связь с практикой
Qt закрывает задачи, где нужен быстрый нативный интерфейс поверх C++: настольные инструменты (Qt Creator, продукты Autodesk, десктоп Telegram), встраиваемые панели в медтехнике и промышленности, приборные интерфейсы в автомобилях. Во всех случаях сначала требуется уверенный C++: классы, наследование, память, сборка — на этом фундаменте стоят QObject, сигналы и слоты.
Освойте тему на практике
Если хочется дойти до рабочего Qt-приложения, начинать логично с языка. На курсе C++ Basic разбирают синтаксис, классы и сборку — базу, без которой Qt воспринимается как магия. Посмотреть формат и темы вживую можно на открытых уроках: там показывают код и отвечают на вопросы в прямом эфире.
FAQ
Нужно ли ставить QML, если я делаю обычное десктоп-приложение?
Нет. Для классического десктопа достаточно модуля Qt Widgets на C++. QML и Qt Quick берут, когда нужен кастомный вид, анимации или мобильный интерфейс. Оба стека ставятся вместе с Qt, но использовать можно только нужный.
Можно ли писать на Qt без глубокого знания C++?
Через привязки PyQt или PySide интерфейс делают на Python. Но сам фреймворк проектировался под C++, и большинство документации, примеров и вакансий завязаны на него, поэтому C++ остается базовым навыком для Qt.
Зачем нужен moc и почему нельзя обойтись стандартным C++?
Сигналы, слоты и свойства требуют метаинформации об объекте во время выполнения, которой в стандартном C++ нет. moc генерирует эту информацию как дополнительный код на этапе сборки; при использовании qmake или CMake он вызывается автоматически.



