Перейти к основному содержимому

Qt — первая программа

Разработчику Архитектору
О чём эта статья

Первое настольное окно на C++ с Qt 6 Widgets — кнопка, надпись, связь через сигналы и слоты.

Сборка — CMake (CMake — первая программа).

Декларативный UI — Qt Quick.

Обзор экосистемы — Qt.


Qt Widgets — первое окно на C++

Если вы знакомы с C++, но ещё не собирали GUI, здесь — короткий путь к рабочему результату.

ТерминПростыми словами
Qtбиблиотека для интерфейса, сети, файлов, многопоточности
Qt Widgetsклассические кнопки и окна (как в офисных программах)
Виджетпрямоугольный элемент UI: кнопка, надпись, поле ввода
Сигнал / слот"событие произошло" → "выполнить реакцию"
mocMeta-Object Compiler — генерирует код для сигналов (включается CMAKE_AUTOMOC)

Qt Widgets удобен для учебного старта: мало "магии", видна иерархия объектов. Qt Quick (QML) — отдельная статья Qt Quick — первая программа на QML.


Модель событий в GUI

Desktop-приложение не опрашивает кнопки в цикле while. Вы описываете реакции на сигналы (clicked, textChanged, timeout) и отдаёте управление app.exec(). Это главный переход от консольного кода к Qt.


Что получится в конце

Окно с надписью и кнопкой. По нажатию текст меняется — без цикла while (кнопка нажата?). Связь делает connect.

┌─────────────────────────────┐
│ Qt Hello │
│ │
│ Нажмите кнопку │
│ ┌─────────┐ │
│ │ Click │ │
│ └─────────┘ │
└─────────────────────────────┘

Установка Qt 6

Нужны: компилятор C++17, CMake 3.20+, Qt 6 с модулем Qt Widgets.

СпособКогда удобно
qt.io/downloadWindows/macOS, выбор MSVC/MinGW
Пакеты ОС (qt6-base-dev и аналоги)Linux, CI
Qt Creatorпуть к Qt подставляется в CMAKE_PREFIX_PATH

Запомните каталог kit, например C:/Qt/6.7.0/msvc2019_64 — его передают в CMake как CMAKE_PREFIX_PATH.

Проверка

В kit есть bin/qmake (или bin/qt-cmake) и lib/cmake/Qt6. Ошибка Could not find Qt6 почти всегда означает неверный CMAKE_PREFIX_PATH.


Структура проекта

qt-hello/
├── CMakeLists.txt
└── main.cpp
ФайлРоль
CMakeLists.txtцель qt_hello, Qt6::Widgets, AUTOMOC
main.cppокно, виджеты, connect

В больших проектах логику выносят в MainWindow, формы — в .ui. Для первого шага достаточно одного main.cpp.


CMakeLists.txt — построчно

cmake_minimum_required(VERSION 3.20)
project(qt_hello LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

find_package(Qt6 REQUIRED COMPONENTS Widgets)

add_executable(qt_hello main.cpp)
target_link_libraries(qt_hello PRIVATE Qt6::Widgets)

Разбор:

  • Это минимальный конфигурационный файл CMake для Qt Widgets-приложения.
  • CMAKE_AUTOMOC, CMAKE_AUTORCC и CMAKE_AUTOUIC включают автоматические генераторы Qt, чтобы не запускать их вручную.
  • find_package(Qt6 ... Widgets) подключает модуль интерфейса и валидирует наличие Qt в toolchain.
  • add_executable создаёт исполняемый файл, а target_link_libraries линкует его с Qt6::Widgets.
  • Такой шаблон масштабируется: при росте проекта в цель просто добавляют новые .cpp/.h/.ui.
СтрокаЗачем
CMAKE_AUTOMOC ONзапуск moc для классов с Q_OBJECT
AUTORCC / AUTOUICресурсы и формы Designer (пока не используем, привычка полезна)
find_package(Qt6 ... Widgets)только модуль виджетов, не весь Qt
Qt6::Widgetsлинковка с библиотекой виджетов

Конфигурация (подставьте свой путь):

cmake -S . -B build -DCMAKE_PREFIX_PATH="C:/Qt/6.7.0/msvc2019_64"
cmake --build build
./build/qt_hello # или build\qt_hello.exe на Windows

Событийный цикл — зачем QApplication

Консольная программа завершается на return из main. GUI должно ждать клики и клавиши.

ШагКодСмысл
1QApplication app(argc, argv);одно приложение на процесс
2создать окно и виджетыдерево объектов
3window.show();сделать окно видимым
4return app.exec();цикл событий до выхода

Без exec() окно может мелькнуть и исчезнуть — частая ошибка новичка.


main.cpp — полный код и разбор

Код ITЗагрузка примера кода…

Разбор:

  • Фрагмент показывает полный жизненный цикл простого Qt-приложения от инициализации до запуска event loop.
  • QApplication создаёт контекст GUI, затем QWidget window выступает корневым окном.
  • Через QObject::connect кнопка отправляет сигнал, а лямбда-обработчик меняет текст метки.
  • QVBoxLayout берёт на себя компоновку элементов и корректную перестройку при изменении размера окна.
  • app.exec() запускает цикл событий, где обрабатываются клики, перерисовка и ввод пользователя.

Шаг 1. QApplication

argc / argv — Qt может обрабатывать флаги вроде -style на некоторых платформах.


Шаг 2. Окно-контейнер

QWidget window — верхнеуровневое окно. setWindowTitle — заголовок в рамке ОС.


Шаг 3. Родитель и владение

auto* label = new QLabel("...", &window);

Разбор:

  • Здесь создаётся QLabel и сразу назначается родитель &window.
  • Родительская иерархия Qt автоматически управляет удалением дочерних объектов вместе с окном.
  • Такой подход упрощает работу с памятью в UI и снижает количество ручного delete.
  • В виджетных приложениях это базовый паттерн владения для большинства объектов интерфейса.
  • Текст в конструкторе задаёт стартовое состояние элемента на экране.

Второй аргумент — родитель &window. При уничтожении родителя Qt удаляет детей. В простых примерах часто пишут new без delete — это дерево владения Qt. В больших проектах владение всё равно проектируют явно (Qt - кроссплатформенный фреймворк на C++).


Шаг 4. connect — разбор по частям

QObject::connect(button, &QPushButton::clicked, [label]() {
label->setText("Привет из Qt!");
});

Разбор:

  • QObject::connect формирует связь "сигнал -> обработчик" без жёсткой зависимости между элементами.
  • &QPushButton::clicked выбирает строго типизированный сигнал кнопки, который срабатывает при нажатии.
  • Лямбда [label] захватывает указатель на метку и выполняет обновление текста в момент события.
  • Реакция выражена локально рядом с местом создания кнопки, поэтому код проще читать новичку.
  • Это короткий пример механизма сигналов и слотов, на котором строится событийная модель Qt.
ЧастьСмысл
buttonотправитель
&QPushButton::clickedсигнал "нажали и отпустили"
[label]() { ... }слот-лямбда: захватывает указатель на label
setTextобновление UI

Кнопка излучает сигнал; она не знает про QLabel напрямую — связь задана снаружи.


Шаг 5. Layout

QVBoxLayout выстраивает виджеты столбиком и пересчитывает геометрию при resize.


Сигналы и слоты — чуть глубже

  • Один сигналнесколько слотов возможно.
  • Один слотнесколько сигналов возможно (осторожно с побочными эффектами).

Для прототипа удобны лямбды. В рабочем коде чаще метод класса:

class MainWindow : public QWidget {
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = nullptr);
private slots:
void onClicked();
private:
QLabel* label_;
};

connect(button, &QPushButton::clicked, this, &MainWindow::onClicked);

Класс с Q_OBJECT обязан проходить через moc → CMAKE_AUTOMOC ON.


Частые ошибки

СимптомВероятная причина
Окно не появляетсянет show() или выход из main без exec()
Could not find Qt6неверный CMAKE_PREFIX_PATH
moc / vtableнет AUTOMOC или забыт Q_OBJECT
Клик молчитопечатка в connect, другой объект в лямбде
Текст обрезаннет layout или маленький resize

Что попробовать

  1. Кнопка "Сброс" → текст "Нажмите кнопку".
  2. QHBoxLayout вместо вертикального — элементы в ряд.
  3. Класс MainWindow с Q_OBJECT и слотом onClicked().

Проверка: объясните, кто владеет label и button и зачем нет while(true) для мыши.


Мини-практика для закрепления

  1. Добавьте поле ввода QLineEdit и кнопку "Применить".
  2. По клику устанавливайте текст QLabel из поля ввода.
  3. Если поле пустое, показывайте "Введите текст".

Что вы закрепите:

  • работу с несколькими виджетами;
  • сигнал clicked;
  • простую валидацию пользовательского ввода.

Связанные статьи


Дальше

Десктоп в ITUniverse: /encyclopedia/4-code-dev/4-11-desktopnye-prilozheniya/intro.


В подборках

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Первые шаги (маршрут подборки) — CMake — первая программа, Qt Quick — первая программа на QML, Razor Pages — первая программа, Первая программа на Laravel, .NET MAUI — первая программа, Первая программа на Symfony.