Основы qt. Почему я люблю Qt и вы все тоже должны его любить

Простой пример для ручной сборки

Для лучшего понимания Qt будет правильным выполнить ручную сборку в консоли хотя бы простейшего примера. Методика сборки одинакова для проектов любого размера и важно понимать, как она выполняется.

Рассмотрим простейший пример GUI-приложения, которое выполняет открытие пустого окна на экране. Выделим директорию на диске, где создадим файл main.cpp со следующим содержимым. В пример добавлена нумерация строк для упрощения дальнейших комментариев к примеру. Следует понимать, что нумерация строк не должна содержаться в рабочем файле, так как она не входит в допустимый синтаксис выражений на языке C++.

01. #include 02. #include 03. 04. int main(int argc, char *argv) 05. { 06. QApplication app(argc, argv); 07. QWidget wgt; 08. wgt.setWindowTitle(tr("Hello world")); 09. 10. wgt.show(); 11. return app.exec(); 12. }

В строках 01 и 02 выполняется включение заголовочных файлов QApplication и QWidget , в которых, кроме прочего, содержится объявление классов QApplication и QWidget . В нашем примере мы создаем экземпляры этих классов.

Следует заметить удобную традицию именования заголовочных файлов используемую в Qt. Начиная с четвертой версии Qt, если вам потребовался класс с именем Qxxx , то, скорее всего, его определение находится в заголовочном файле Qxxx .

В данном примере, класс QApplication интересует нас как организатор цикла сбора сообщений, которые будут приходить в окно нашего GUI-приложения. См. строку 11 (запуск цикла обработки оконных сообщений). Класс QApplication реализован по подобию синглтона (Singleton). Для тех, кто не знаком с этим термином из теории шаблонов проектирования (или, паттернов, от англ. patterns ) дадим небольшое пояснение. Суть синглтона заключается в том, что реализация класса предотвращает возможность создания более одного экземпляра данного класса. Эта особенность нам важна потому, что из нее следует возможность определения внутри библиотеки Qt глобальной переменной с указателем на единственный экземпляр данного класса. Смотрите описание для символа qApp в справке Qt.

В библиотеке Qt используется терминология виджета (от англ. widget — штуковина, приспособление), как элемента GUI-интерфейса. Минимальный общий набор свойств таких элементов представлен классом QWidget .

В строках 06 и 07 создаются объекты классов приложения и виджета. В обоих случаях выполняется статическое создание объектов. Время существования таких объектов ограничивается операторным блоком { … } в котором они созданы. Как только исполнение кода программы дойдет до закрывающей скобки, то оба этих объекта автоматически уничтожатся. Таким образом, в данном примере мы не будет задумываться о способе уничтожения объектов Qt и рассмотрим этот вопрос позже.

При создании объекта QApplication используется параметризованный конструктор в который передаются аргументы запуска приложения (копируются из аргументов функции main()). Внутри объекта класса выполняется парсинг этих аргументов. Класс приложения поддерживает ряд параметры запуска, которые можно уточнить по справке для соответствующего конструктора QApplication . Параметры запуска не входящие в этот список следует анализировать самостоятельно. В конце этого урока, разместив в главном окне приложения несколько элементов управления мы предложим провести эксперимент с параметром запуска -style, для которого, в любой сборке Qt, возможны значения: motif , windows , platinum .

В строке 08 выполняется изменение одного из атрибутов объекта виджета. С помощью метода setWindowTitle() мы устанавливаем свой текст для заголовка нашего будущего окна. Обратите внимание, что изображение строки обернуто вызовом функции трансляции tr() . Это требование интернационализации приложения. По всем подобным оберткам, специальными средствами Qt, могут быть созданы специальные файлы с переводами на разные языки, которые можно будет использовать в приложении для выполнения автоматических замен. Обычно, такие файлы включают в сборку приложения в виде ресурсов.

В строке 10 выполняется открытие окна приложения. До версии Qt4, перед открытием окна выполнялась явное объявление виджета как главного виджета приложения. Это делалось с помощью следующего кода.

App.setMainWidget(&wgt);

Начиная с версии Qt4 выполнение такой связи выполняется автоматически через обращение к глобальному указателю qApp на экземпляр класса приложения.

В строке 11 выполняется запуск цикла обработки сообщений операционной системы направленный в окно приложения. Цикл завершается при выполнении какой-нибудь из команд закрытия приложения. Код закрытия приложения возвращается методом exec() при завершении метода. Именно этот код становится кодом возврата функции main() за счет передачи его через оператор return .

Теперь попробуем выполнить сборку приложения. Проще всего это будет сделать в Linux. Для этого надо будет просто открыть консоль и выполнить некоторые команды, которые мы сейчас опишем. Для Windows такая работа может потребовать установку путей на директории размещения утилиты qmake из Qt SDK. Данная утилита реализует правила системы сборки проектов QMake.

Для начала следует узнать, что нам доступно из консоли. Если мы в консоли bash (*nix), то сделать это достаточно просто. Наберите команду qmake и нажмите два раза табуляцию. Мы должны увидеть список всех команд, которые начинаются с сочетания qmake . Например, в моем случае я вижу две команды: qmake и qmake-qt4 . Это говорит о том, что у меня из репозитория установлены две версии библиотеки. Команда qmake соответствует версии Qt5 (действует умолчание для последней версии), а команда qmake-qt4 соответствует, соответственно Qt4. Теперь, в зависимости от того, какой командой я воспользуюсь, я буду делать сборку либо с использованием версии Qt5, либо с использованием версии Qt4.

Если все у нас в системе настроено нормально и версии Qt SDK удачные, то сборка проекта должна быть выполнена с помощью следующих трех команд.

$ qmake -project $ qmake $ make

С помощью первой команды будет создан проектный файл. Проектный файл имеет суффикс .pro . В контексте Windows правильно будет сказать "расширение pro ". Понятия суффикс имени файла и расширение файла означают совершенно разные вещи, хотя и кажутся похожими. Следите за правильностью употребления.

Вторая команда должна создать файл сценария компиляции — Makefile. Третья команда должна выполнить сценарий компиляции, в результате которого должен получиться исполняемый файл приложения.

Если этого не произошло, то попробуем найти проблему.

Откройте проектный файл. Попробуйте найти там следующую строку.

QT += gui

Если такой строки там нет, то следует ее добавить, иначе в зависимости от версии SDK проект может быть воспринят как консольный и в него не будут включены пути на заголовочные файлы классов GUI. Это приведт к тому, что при компиляции будут выведены ошибки о том, что включенные заголовочные файлы не найдены.

Следует иметь в виду, что если вы имеете дело с Qt SDK версии 5, то данное определение должно еще включать группу widgets , как показано ниже.

QT += gui widgets

Пример создания шаблона GUI-приложения из QtCreator

Откройте QtCreator. Для создания нового проекта запустим мастер создания проекта из меню "File->New File or Project …". В открывшемся окне первой страницы мастера предлагается выбрать шаблон будущего проекта. Для группы проектов "Application" выберем вариант "Qt GUI Application" и щелкнем по кнопке "Choose" для перехода на следующую страницу мастера.

На второй странице мастера создания проекта предлагается выбрать имя проекта и директорию его размещения. По указанному имени проекта будет создана поддиректория в которой будут размещены файлы проекта. Создание поддиректории будет выполнено в указанной директории размещения. Таким образом, имя проекта должно определяться правилами которым должно подчиняться имя директории. Однако, чтобы избежать проблем, не используйте русских букв и пробелов. Используйте английские буквы, цифры и символы подчеркивания и тире (знак минуса). Пусть наш проект будет называться app1 . Запишем его в строку name , а в строке выбора директории проекта укажем директорию, где и в дальшейшем будем создавать проекты на Qt. Следует избегать путей с русскими буквами и пробелами. Рано или поздно, они могут вызвать проблемы. Если необходимо запомнить этот путь для следующего раза, установите флажок "Use as default project location". Щелкнем по кнопке "Next" для перехода на следующую страницу мастера.

На третьей странице мастера создания проекта предлагается выбрать Qt SDK из списка найденных и зарегистрированных в QtCreator. Выберите вариант Qt4. Для выбранной версии SDK, следует определить профили сборки проекта. Предлагаются варианты "Release" и "Debug" Сборка "Release" не содержит отладочных символов в исполняемом файле и рекомендуется для передаче в реальное использование. Во всех остальных случаях, удобнее использовать сборку "Debug". В текущем примере, выбор сборки не имеет значения. Можно оставить включенным оба профиля. Справа от названия профиля расположено поле ввода в котором записан путь по которому будет выполняться соответствующая сборка. Часто эти пути редактируют исходя из разных традиций. В нашем примере мы можем оставить эти пути без изменений. Щелкнем по кнопке "Next" для перехода на следующую страницу мастера.

На четвертой странице мастера создания проекта предлагается выбрать имя класса для главной формы проекта, базовый класс, от которого следует унаследовать главную форму проекта и имена файлов, где будет размещен интерфейс и реализация создаваемого класса главной формы. Кроме этого, на странице следует указать будет ли использовано визуальное проектирование формы. Так как мы не будем использовать визуальное проектирование, то следует проследить, чтобы флажок "Generate form" был снят.

Наиболее интересным на четвертой странице мастера создания проекта является выбор базового класса для создания класса формы. Предлагаются три варианта.

  1. QMainWindow — в большинстве случаев, наиболее подходящий выбор. Наследуясь от данного класса мы получаем уже готовые средства для размещения меню, строки статуса и центрального поля, которое можно реализовать как в стиле SDI (Single Document Interface), так и в стиле MDI (Multi Document Interface).
  2. QWidget — этот класс является простейшим виджетом. В терминологии Qt это простейший элемент, с которым связана какая-то графическая область на экране. Как базовый класс для главного окна, используется, как правило, при создании простых одноформенных приложений и отлично подходит для начальных "ученических" целей по причине того, что не содержит ничего "лишнего".
  3. QDialog — базовый класс для создания модальных диалоговых окон.

Для нашего примера, выберем в качестве базового класса, простейший вариант — QWidget . Имена для главного класса формы и для файлов, где будет размещаться его интерфейс и реализация можно оставить значениями по-умолчанию. Щелкнем по кнопке "Next" для перехода на следующую страницу мастера.

Пятая страница мастера создания проекта позволяет определить связь создаваемого проекта с уже открытыми проектами и указать выбор какой-нибудь доступной системы управления версиями проекта. В текущем примере нас не интересуют данные возможности, поэтому нам следует завершить работу мастера щелкнув кнопку "Finish".

В разных версиях QtCreator шаги по созданию проекта могут несколько отличаться, но, по сути, здесь изложены главные моменты, которые следует понимать при создании GUI-проекта. Текущее описание делалось на основе версии QtCreator 2.7.0.

После выполнения мастера создания проекта в QtCreator откроется вид с созданным проектом. Выполните запуск проекта, чтобы проверить настройки среды разработки. Если все в порядке, то созданный шаблон проекта должен откомпилироваться и запуститься. Для обычного запуска проекта можно воспользоваться щелчком по кнопке с изображением зеленого треугольника, размещенной на панели инструментов. Кнопка с изображением зеленого треугольника с жуком выполняет функции запуска в режиме отладке. В этом случае, если в проекте установлены точки останова, то при их достижении, выполнение запущенного приложения остановится и в редакторе отладке подсветится строка на которой был выполнен останов.

QtCreator заметно отличается своим дизайном от других сред разработки. Однако, его дизайн удивительно эргономичен. Кроме прочего, в эпоху широких экранов, очень выгодно смотрится панель инструментов расположенная слева в главном окне среды разработки. В нижней части панели инструментов, как уже говорилось, расположены кнопки запуска приложения, а в верхней — кнопки выбора вкладок для главного окна среды разработки. Рассмотрим список основных вкладок.

  • "Welcome" — Выбор проекта
  • "Edit" — Редактирование программы.
  • "Debug" — Отладки проекта. Включает необходимые окна для наблюдения за объектами.
  • "Projects" — Настроки проектов, загруженных в среду разработки. Следует внимательно изучить возможности представленные на этой вкладке
  • "Analyze" — Анализ проектов с помощью специальных средств обнаружения узких мест в быстродействии и проблем утечки памяти.
  • "Help" Окно интергрированной справки. Возможно, вам больше понравится работать с отдельным справочным приложением QtAssistant.

Простой пример размещения виджетов в окне приложения

Возьмем проект, который мы создали в предыдущем разделе с помощью мастера среды разработки QtCreator. Созданный проект включает в себя следующие файлы.

  • app1.pro — файл проекта
  • main.cpp widget.h и widget.cpp ./li>
  • widget.h — интерфейс класса главного окна приложения.
  • widget.cpp — реализация класса главного окна приложения.

Возможно, имена файлов в вашем проекте несколько отличаются. Это может быть либо потому, что вы их явно указали другими, при создании проекта, либо значения по умолчанию для вашей версии QtCreator иные.

Откроем файл реализации главного окна приложения — widget.cpp . Изменим его до состояния представленного в следующем примере. Помните, что номера строк указаны только для удобства комментариев.

01. #include 02. #include 03. #include 04. 05. #include "widget.h" 06. 07. Widget::Widget(QWidget *parent) 08. : QWidget(parent) 09. { 10. setWindowTitle(tr("Hello world!!!")); 11. setMinimumSize(200, 80); 12. 13. QLabel * plb = new QLabel(tr("Test"), this); 14. plb->setGeometry(20, 20, 80, 24); 15. 16. QLineEdit * ple = new QLineEdit(this); 17. ple->setGeometry(110, 20, 80, 24); 18. 19. QPushButton * ppb = new QPushButton(tr("Ok"), this); 20. ppb->setGeometry(20, 50, 80, 24); 21. } 22. 23. Widget::~Widget() 24. { 25. 26. }

В строках 01-03 выполняется включение файлов с интерфесами следующих классов виджетов.

  1. QLabel — класс метки. Часто используется для размещения статической текстовой информации. Понимает некоторые теги HTML для форматирования. Может быть использован для статического размещения изображения. Например, из файла с картинкой. Наследуется от QFrame , поэтому может настраиваться на различные формы окантовки (бордюра).
  2. QLineEdit — класс для создания однострочных полей ввода текстовой информации.
  3. QPushButton — класс кнопки. Чаще всего используется для обработки сигнала clicked() — щелчок по кнопке.

Тело конструктора класса Widget содержит две строки настройки атрибутов окна (строки 10-11) и 8 строк создания и размещения на поле окна трех других виджетов (строки 13-20).

Настройка атрибутов окна состоит из команду установки имени окна приложения и минимального размера окна приложения. Для задания минимального размера использован метод, принимающий значения ширины и высоты окна в пикселях.

Строка 13 содержит создание экземпляра класса QLabel. Объект создается динамически, через оператор new. Для создания объекта используется конструктор, первым параметром которого указывается строка, которую должен изображать создаваемый объект. Вторым параметром данного конструктора следует указать адрес объекта, который станет владельцем создаваемого объекта метки. В качестве адреса владельца указано значение this . По правилам языка C++, this является указателем на объект внутри которого он используется. Т.е., в данном контексте, это указатель на созданный экземпляр класса Widget . Таким образом, в строке 13 создается объект класса метки, который должен изображать указанный текст и владельцем которого назначается текущий объект.

Здесь пришло время рассказать о цепях владения, которые реализованы в системе классов Qt для решения проблемы уничтожения объектов для предотвращения случайных утечек памяти. Следует вспомнить, что объекты созданные динамически, т.е. с помощью оператора new , размещаются в специальной области памяти, называемой кучей (heap) и которые живут в куче до тех пор пока не будут явно уничтожены оператором delete . Если программист не отслеживает уничтожение объектов, которые стали ненужными и не вызывает для их уничтожения оператор delete , то это становится причиной утечки памяти в приложении, которая является серьезной проблемой для ряда языков программирования в группу которых входит язык C++.

Существует несколько известных схем автоматического слежения за уничтожением динамически созданных объектов. Один из них заключается в использовании умных указателей, о которых, следует рассказать позже. Другой способ заключается в создании цепей владения, о котором мы сейчас расскажем. Третьим способом является создание подсистемы уборки мусора, которая должна отлеживать ненужные объекты и уничтожать их. Последний способ, традиционный для ядер многих современных языков, в C++ практически не используется. Гораздо более популярными в традициях языка C++ являются первые два способа.

Итак, цепи владения реализуют следующую простую идею. Создается некоторый объект, за уничтожением которого мы обязуемся следить. Проще всего создать такой объект статическим определением и тогда он уничтожится автоматически, когда исполнение программы достигнет конца операторного блока { … } в котором он был определен. Далее, при динамическом создании других объектов будем назначать для них объекты владельцев. В обязанности владельцев будет входить уничтожении владеемых объектов в теле собственного деструктора. Напомним, что деструктор — это особый метод, который вызывается при уничтожении объекта. Таким образом, можно построить такую цепь владения относительно первого объекта, все элементы которой будут автоматически уничтожены при уничтожении первого объекта. При организации такой схемы следует лишь правильно учитывать время жизни объекта, который назначается владельцем другого объекта, чтобы объекты не были уничтожены преждевременно.

Именно такая схема владения реализована в системе классов Qt. При создании многих классов из этой библиотеки можно воспользоваться конструктором, который единственным или последним параметром принимает указатель на объект, который назначается владельцем к создаваемому объекту. Параметр этот описывается как параметр со значением по умолчанию, которое определяется как ноль. Таким образом, если адрес владельца не указывается, то параметр получает значение ноль и схема владения для такого объекта отключается. В этом случае следует помнить о явном уничтожении такого объекта.

При реализации схем цепей владения, в некоторых библиотеках используется параметр с именем owner , что с английского языка переводится как владелец . Однако в библиотеке Qt такой параметр называется parent , что переводится с английского как родитель . В результате этого, у некоторых новичков возникает недопонимание образованное тем, что понятие "родитель" традиционо относится к цепям наследования в ООП, однако цепи наследования и цепи владения не имеют ничего общего. Будьте внимательны и не становитесь жертвой заблуждения в этом вопросе.

Вернемся еще раз к строке 13. Там мы создали объект владельцем которого назначен текущий объект главного окна приложения. Переменная plb , которая хранит адрес созданного объекта будет уничтожена автоматически при достижении конца кода конструктора. Однако объект который был распределен в памяти останется жить и далее, и будет жить до тех пор, пока объект главного окна приложения не будет уничтожен. При уничтожении объекта главного окна будут автоматически уничтожены все объекты, которыми объект окна владеет.

В строке 14 мы обращаемся к методу задания атрибутов геометрии, которые определяют размещение настраиваемого объекта относительно своего владельца. Первым и вторым значением указываются горизонтальная и вертикальная координата для верхнего левого угла объекта. Третьим и четвертым значением указывается ширина и высота настраиваемого объекта.

Если вы добились того, что пример, созданный в предыдущем разделе собрался и запустился без ошибок, то должен выполниться и этот пример, который является расширением предыдущего.

Используя данное приложение можно поэкспериментировать с параметрами запуска приложения. Проще всего это сделать в консоли. Зайдите в директорию сборки приложения и выполните следующие варианты запуска приложения с параметрами. В каждом из запусков должна быть заметна разница в стиле прорисовки виджетов.

$ ./app1 -style=motif $ ./app1 -style=windows $ ./app1 -style=platinum

В данном примере, исполняемый файл приложения указан именем app1 . Возможно, что в вашем случае, исполняемый файл имеет другое имя. В операционной системе Windows, исполняемые файлы имеют расширение exe . Кроме того, в операционной системе Windows, выполнить запуск исполняемого файла из текущей директории можно без указания относительного пути, т.е. без указания (./ ) — символ точки является синонимом текущей директории, а символ прямого слеша — символом разделителя в записи файловых путей. Также, следует иметь в виду, что символ доллара — это символ стандартного приглашения в консоли *nix для обычного пользователя и набирать его частью команды не нужно. В консоли Windows, символом приглашения обычно является символ угловой скобки (> ).

Параметры запуска, также можно указать при запуске приложения из среды разработки QtCreator. Для этого щелкните на панели инструментов слева по значку Projects . Откроется соответствующая вкладка с настройками. В верхней части окна можно видеть иерархическую систему вкладок. Вкладки самого верхнего уровня определяют проект, так как в среде разработки могут быть открыты несколько проектов. Следующий уровень вкладок, кроме прочего, должен содержать вкладку Build&Run , которая нам нужна. В этой вкладке далее следует выбор версии Qt SDK, для случая, если вы делаете сборку проекта сразу под несколько версий. Если вы собираете проект под одну версию, то выбор будет состоять из одного элемента. Внутри виджета выбора версии Qt SDK, расположены две стилизованные кнопки с закругленными краями — кнопки Build и Run . Щелкните по кнопке Run , чтобы выбрать соответствующую группу настроек. Там, в одноименной группе параметров Run вы найдете однострочное поле ввода напротив метки Arguments . Это и есть конечная цель нашего выбора. Запишем туда следующую строку.

Style=motif

Запустите приложение. Потом попробуйте другие значения: windows и platinum . Напомним, что объект класса QApplication поддерживает список из пары десятков параметров запуска, о которых можно прочитать в справке по соответствующим конструкторам класса.

Работая над примером, познакомьтесь со справочной информацией по используемым в примере классам. Попробуйте добавить на форму другие экземпляры классов метки, однострочного поля ввода и кнопки. Кроме этого, попробуйте познакомиться со справкой и добавить на форму объекты следующих классов.

  1. QComboBox — класс выпадающего списка.
  2. QCheckBox — класс флажка (чекера).
  3. QTextEdit — класс многострочного поля ввода. Используется как для редактирования, так и для представления текста. Содержит очень богатые возможности по представлению документов за счет выделения функций специальных компоновщиков документов в отдельные классы.

В заключении урока следует заметить, что используемый способ "жесткого" размещения объектов на поле формы, через явное указание геометрии размещения не является традиционным и рекомендуемым в библиотеке классов Qt. В следующих уроках будут рассмотрены менеджеры компоновки, которые являются современными и удобными средствами размещения виджетов на форме.

После суток жизни поста я начал замечать утечку кармы, так что заранее прошу прощение за возможно недопустимый стиль изложения в статье и субъективизм

Привет, Хабрахабр!

Последнее время я не мог не обратить внимание на популярность темы Qt на хабрике, но тем не менее, в комментах продолжают встречаться люди, которые говорят откровенно лживые и непонятные вещи. Этим постом я хотел развеять малость заблуждений о Qt и рассказать, почему же ты должен пересесть со своих Java/Obj-C/.NET на мягкий и пушистый Qt .

Под катом будет много впечатлений, субъективностей и моих скромных мнений на счет самого замечательного фреймворка для разработки приложений. Впрочем, я постараюсь добавить интересностей, чтобы моя статья приобрела хоть какой-то техническополезный смысл. Надеюсь, получится занимательное чтиво и вам понравится.

Ну, что, поехали?

Вешч №1. С++ API

Ни для никого не секрет, что у Qt очень удобное API, а конкретнее говоря, модуль qtbase содержит достаточное количество классов для большинства повседневных задач (Qt - это больше, чем GUI фреймворк, лол ). Я уже говорил об обертках STL-ных контейнеров в своей статье трехгодичной давности - тыцк . Классы для работы со строками, отладочный вывод, и много-много чего, так же included.

QString fruits = "apple, banana, orange, banana"; QStringList fruitsList = fruits.split(", "); qDebug() << fruitsList; // выведет в консоль [ "apple", "banana", "orange", "banana" ] fruitsList.removeDuplicates(); fruits = fruitsList.join(", "); qDebug() << fruits; // выведет в консоль "apple, banana, orange"
Стоит сказать, что у Qt также есть модули для удобной работы с XML, базами данных (с интеграцией вкусной-превкусной кьютешной системой MVC ), OpenGL, аудио/видео-работы (Phonon), сетевого программирования, WebKit2. Для больниства задач, которые стоят перед среднестатистическим проектом - этой кухни хватает в 90% случаев, а с модулями редко случаются з*ебы.

С учетом моей любви к C++, я очень и очень сильно доволен тем, какую поддержку различных нетривиальных вещей Qt представляет на кросс-платформенном уровне. Пару раз приходилось разруливать особо непонятные моменты, но это такое.

Вешч №2. Qt Quick

Qt Quick - это мегасмачный подход к созданию графического пользовательского интерфейса. Используя декларативный язык QML (угадайте, где его придумали, лол), похожий на JavaScript, можно добиться высокой производительности при прототипировании интерфейса в приложениях любой сложности. А самое забавное, что при таком ходе дел, с прототипированием интерфейса может справиться даже дизайнер, который знает синтаксис JavaScript . Это все были бы пустые слова, если бы я не показал вам пример функционального кода (больше можно найти на Qt Project - тамц).

Import QtQuick 2.0 Rectangle { id: page width: 320; height: 480 color: "lightgray" Text { id: helloText text: "Hello world!" y: 30 anchors.horizontalCenter: page.horizontalCenter font.pointSize: 24; font.bold: true } Grid { id: colorPicker x: 4; anchors.bottom: page.bottom; anchors.bottomMargin: 4 rows: 2; columns: 3; spacing: 3 Cell { cellColor: "red"; onClicked: helloText.color = cellColor } Cell { cellColor: "green"; onClicked: helloText.color = cellColor } Cell { cellColor: "blue"; onClicked: helloText.color = cellColor } Cell { cellColor: "yellow"; onClicked: helloText.color = cellColor } Cell { cellColor: "steelblue"; onClicked: helloText.color = cellColor } Cell { cellColor: "black"; onClicked: helloText.color = cellColor } } }

Имплементация объекта Cell крайне тривиальна и определена таким образом

import QtQuick 2.0 Item { id: container property alias cellColor: rectangle.color signal clicked(color cellColor) width: 40; height: 25 Rectangle { id: rectangle border.color: "white" anchors.fill: parent } MouseArea { anchors.fill: parent onClicked: container.clicked(container.cellColor) } }

В этом коде нету ни строчки С++ и он нормально работает. Годно, не так ли? Я себя даже волшебником от этого почуствовал - проще в магазин за хлебом сходить, чем приложение вот такое склепать. Тем не менее, в сложных приложениях не хватает одного QML и мы объединяем его с С++. Об этом шла речь в многих статьях хаба Qt Software - например, тамц .

Вешч №3. Сообщество

Ну вот мы и дошли до приятного момента. Если говорить о мне, то я работаю с Qt относительно мало - всего 5 лет. Qt проводит ежегодные мероприятия - Qt Developer Days и Qt Contributors" Summit. Я был на каждом из них по одному разу, в прошлом году, и мне очень понравилось - уровень подготовки высокий, а впечателения доставляют. Мне также приходилось общаться с «ветеранами» Qt - людьми, которые посещали саммит на протяжении 10 лет. Представляю, насколько круто на своих глазах видеть рост такого проекта и быть в эпицентре всей разработки - просто смачненько.

К новичкам эти люди очень терпимы и относятся хорошо, мне было очень легко и прятно навести контакты с такими замечательными людьми. На Qt Project есть форумы, где каждый желающий может получить ответ на волнующий его вопрос. Забавно, но девнет действительно очень живой и там реально отвечают на вопросы, возникающие, в процессе познания Qt.

Вешч №4. Открытый исходный код и code review

Сорец кьюта открыто разрабатывается в основном, компаниями Digia (комм. поддержка +), KDAB, ICS и энтузиастами-разработчиками. Хостится все это дело на Gitorious - тадамц . Чтобы внести свою лепту в развитие проекта, нужно пройти строгую проверку кода - автоматизированную (соблюдения стиля кода, о котором я уже писал ранее - птссс) и человеческую - твой код будут смотреть бородатые дяди, которые не доверяют тебе и будут искать в твоем коде бэкдоры. Все это достаточно сложный процесс (заморочки с Git / ревизии на Review Board) и я наверное напишу об этом статью на днях.

У меня, к слову, есть пару коммитов в дереве qtbase, так что можете спрашивать в лс - попробую ответить на вопросы.

Вешч №5. Динамика развития проекта

Qt разрабатывается уже много лет, с конца 90-х. За это время его коммерческой версией уже успели наиграться такие компании, как Trolltech и Nokia, а сейчас этим занимается Digia. Но одно можно точно сказать, проект живет и процветает. Еще несколько лет дизайн все писали на виджетах (С++ классы, все до единого основанные на QWidget), а сегодня его может сделать и маленький ребенок. Думаю, не стоит говорить, что параллельно с ним активно развивается мошнейшая вешч - Qt Creator, который сегодня радует не только Qt программистов!

^ классненький Qt Creator, в котором можно творить чудеса и тебе за это ничего не будет .

К сожалению, у меня нету строгих чисел, но говорят, что код каждый день оптимизируется, а codebase тщательно наращивается - добавляются новые фичи и исправляются старые баги (в этом то я успел убедиться уже много раз). Все это очень годно и не может не радовать.

К тому же, сейчас идет активное развитие платформ iOS, Android, Windows Phone , уже сейчас можно собирать под них программы!

Итог

Я думаю вы понимаете, что Qt - это правда круто и после прочтения статьи вы полюбили его так же, как и я.
Спасибо за внимание!

Это кросс-платформенный инструментарий разработки ПО на языке программирования C++. Есть также «привязки» ко многим другим языкам программирования: Python - PyQt, Ruby - QtRuby, Java - Qt Jambi, PHP - PHP-Qt и другие.
Позволяет запускать написанное с его помощью ПО в большинстве современных операционных систем путём простой компиляции программы для каждой ОС без изменения исходного кода. Включает в себя все основные классы, которые могут потребоваться при разработке прикладного программного обеспечения, начиная от элементов графического интерфейса и заканчивая классами для работы с сетью, базами данных и XML. Qt является полностью объектно-ориентированным, легко расширяемым и поддерживающим технику компонентного программирования.
В этой статье я покажу как написать простую программу «Hello, World!» с использованием библиотеки Qt4

Среда разработки

Сначала определимся со средой разработки. Лично я для написания программа использую кросс платформенную IDE Code::Blocks (подробнее про работу в этой IDE с Qt4 можно почитать ). Так же есть плагины для работы с Qt в Eclipse. Коммерческая версия Qt под MS Windows может быть интегрирована в MSVS. Программы так же можно писать в любом текстовом редакторе, а потом компилировать их из командной строки.
Для наглядности, я покажу как компилировать программы, написанные на Qt, вручную.

Первая программа

Сначала в любом текстовом редакторе создадим файл и назовем его, например, main.cpp
Напишем в нем следующее:
  1. #include
  2. #include
  3. QApplication app(argc, argv);
  4. QDialog *dialog = new QDialog;
  5. QLabel *label = new QLabel(dialog);
  6. label->setText("Hello, World!" );
  7. dialog->show();
  8. return app.exec();

В строках 1 и 2 мы подключили заголовочные файлы Qt в которых находятся основные классы.
В строке 4 мы объявили функцию main - главную функцию, с которой начинается выполнение любой программы. Она возвращает целое число (результат работы программы; 0 - если все в порядке) и принимает на вход две переменные - число параметров командной строки и массив, в котором они сохранены.
В строке 5 мы создаем объект приложения. Этому объекту мы передаем переменные командной строки.
В строке 6 мы создаем диалог - графическое окно прямоугольной формы, с заголовком и кнопками в верхнем правом углу. Создаем метку (строка 7). При создании метки мы передаем ее конструктору указатель на диалог, который становится ее родителем. При удалении родителя автоматически удаляются все его потомки, что очень удобно. Затем устанавливаем надпись метки путем вызова функции setText() (строка 8). Как видно из примера, для отображаемого текста можно использовать html-теги.
В строке 9 мы отображаем наше диалоговое окно с меткой на экране.
И, наконец в строке 10 мы запускаем цикл обработки событий операционной системы приложением. Результат работы объекта мы возвращаем как результат работы программы.

Компиляция

Теперь скомпилируем написанную программу.
Перейдем в каталог, куда мы сохранили наш файл main.cpp и выполним команду

$ qmake -project

При этом произойдет создание заготовки проекта Qt4, в который автоматически будут включены все файлы исходных кодов, лежащих в данной директории. В результате получится файл с именем как у текущей директории и расширением.pro. Он будет выглядеть следующим образом:

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

# Input
SOURCES += main.cpp

В результате мы получим Makefile, который используем для того что бы скомпилировать программу, выполнив следующую команду:

Подождем пока процесс компиляции не закончится и запустим нашу первую программу. Она будет выглядеть примерно так:

Вторая программа

Что бы получить полный контроль над создаваемыми окнами и другими виджетами, необходимо создавать производные от них классы. Создадим производный класс MyDialog. В качестве родительского будем использовать класс QDialog. Описание нашего класса поместим в заголовочный файл mydialog.h:
  1. #include
  2. #include
  3. #include
  4. #include
  5. class MyDialog: public QDialog {
  6. Q_OBJECT
  7. public :
  8. MyDialog(QWidget *parent = 0);
* This source code was highlighted with Source Code Highlighter .
В первых четырех строках мы подключаем необходимые заголовочные файлы используемых графических элементов - диалога, кнопки, надписи и вертикального менеджера компоновки. Использовать такие крупные заголовочные файлы как , и др. в больших проектах не рекомендуется, так как это увеличивает время компиляции.
В шестой строке мы определили наш класс производным от QDialog.
На следующей строчке мы указали макрос Q_OBJECT, который указывает предпроцессору Qt что данный класс будет использовать дополнительные возможности Qt, например, систему сигналов и слотов.
На строке 9 мы указываем конструктор нашего диалогового окна. У него только один входной параметр - указатель на родительский объект (0 если родителя нет).
Конструктор нашего класса мы определим в файле mydialog.cpp:
  1. #include "mydialog.h"
  2. MyDialog::MyDialog(QWidget *parent) : QDialog(parent) {
  3. QVBoxLayout *layout = new QVBoxLayout(this );
  4. QLabel *label = new QLabel(this );
  5. label->setText("Hello, World!" );
  6. QPushButton *button = new QPushButton(this );
  7. button->setText("Close" );
  8. layout->addWidget(label);
  9. layout->addWidget(button);
  10. connect(button, SIGNAL(clicked()), this , SLOT(close()));
* This source code was highlighted with Source Code Highlighter .

В строке 4 мы создаем менеджер компоновки, который будет автоматически отображать все добавленные в него виджеты вертикально. Создание надписи аналогично предыдущему примеру.
В строках 7 и 8 создаем кнопку и устанавливаем ее текст. На следующих двух строчках мы добавляем наши виджеты в менеджер компоновки что бы он их автоматически упорядочил.
В строке 11 мы подключаем сигнал нажатия clicked() кнопки button к слоту close() нашего диалогового окна. У каждого объекта Qt могут быть свои сигналы и слоты, которые можно подключать к сигналам и слотам других объектов и таким образом осуществлять коммуникацию между элементами программы.
Файл main.cpp примет следующий вид:
  1. #include
  2. #include "mydialog.h"
  3. int main(int argc, char * argv) {
  4. QApplication app(argc, argv);
  5. MyDialog *dialog = new MyDialog;
  6. dialog->show();
  7. return app.exec();
* This source code was highlighted with Source Code Highlighter .

Пересоздаем проект командой

$ qmake -project

Что бы новые файлы автоматически в него добавились и компилируем его. Вот так выглядит наша новая программа:

Третья программа

Если диалоговое окно содержит много графических элементов, то создавать такие окна довольно утомительно. Для упрощения этого процесса есть инструмент под названием Qt Designer. Запускаем его

И выбираем создание диалогового окна без кнопок. Добавляем на него метку и кнопку, редактируем их текст. С помощью инструмента редактора сигналов и слотов (Signal/Slot Editor) подключаем сигнал нажатия clicked() кнопки button к слоту close() диалогового окна. Располагаем их вертикально с помощью менеджера компоновки. Сохраняем полученный файл под именем mydialog.ui. Позже он будет автоматически преобразован в заголовочный файл с именем ui_mydialog.h.
Изменяем заголовочный файл нашего диалогового окна mydialog.h следующим образом:

Начинающий программист постоянно сомневается, какие технологии начать осваивать эту или какую-нибудь другую. Нужно ли начинающему программисту изучать Qt? Однозначно, нужно! Например, почитайте этот пост или поищите что-нибудь в интернете. Всё ещё не уверены нужен ли Вам Qt? Если Вы пишите на С++, Qt вы должны знать, у Вас просто нет другой альтернативы.

Итак, поехали...

Давайте, для примера, напишем простенький калькулятор - сложение двух чисел.

Создаём новый проект. Как мы видем, существует несколько типов приложений. Мы как начинающие, выбираем "Приложение Qt Widgets":

Указываем имя проекта и папку для размещения файлов, у меня: C:\projects\qt

Qt автоматически генерирует следующие файлы:

  • lesson1.pro - файл проекта
  • main.cpp - главный файл с фукнцией main()
  • mainwindow.cpp - исходный код главного окна
  • mainwindow.h - заголовочный файл главного окна
  • mainwindow.ui - файл формы главного окна

Нажимаем кнопку "Завершить" - открывается редактор для разработки программ на Qt.

Пока должно быть всё понятно для начинающего Qt-разработчика...

Открываем главную форму (для этого переходим в mainwindow.ui).

Слева располагаются компоненты для создания экранной формы, справа сама форма, она пустая. Накидаем нужные компонентики, незабудем поля ввода QLineEdit назвать так: edtA, edtB и edtC соответственно.

Мы видем на экране поля ввода, подписи к ним слева и кнопку "A + B =". При нажатии на эту кнопку мы должны сложить A и B и поместить результат в C.

Как быть? Любой начинающий Qt-разработчик предположит, что нужно навесить на кнопку обработчик нажатия этой кнопки и он будет прав! В любых других фреймворках есть такое понятие как событие . Но в Qt решили выпендриться и придумали сигналы/слоты. Хотя, по сути, это, практически, тоже самое.

Кликаем правой кнопкой мыши на кнопку "A + B =", открывается всплывающее меню:

жмём на "Перейти к слоту"

Выбираем сигнал clicked() , и в открывшемся редакторе кода пишем небольшой программный код на Qt:

Void MainWindow::on_btnOK_clicked() { int a = ui->edtA->text().toInt(); // Берем текст edtA и преобразовываем его в число a int b = ui->edtB->text().toInt(); // Берем текст edtB и преобразовываем его в число b int c = a + b; // Складываем числа QString s = QString::number(c); // Преобразуем результат в строковый вид ui->edtC->setText(s); // Вывести результат в edtC }

Функция обработки сигнала clicked() называется слотом on_btnOK_clicked().

tl;dr — Qt библиотека для создания кроссплатформенных оконных приложений на C++.

Qt, как проект, зародился из желания разработчиков C++ иметь удобный инструментарий разработки графических интерфейсов программ (GUI). Если, например, в Java для этих целей из коробки идет AWT, а в Python Tk, то в С++ не было ничего подобного. И не только того что касается разработки GUI, а так же классов работы с сетью, мультимедиа и прочих очень востребованных вещей. Чему очень досадовали разработчики. Ну а раз есть спрос, то предложение не заставило себя долго ждать. В 1995 году вышел первый релиз библиотеки. С тех пор Qt быстро стал расширяться за пределы всего-лишь разработки интерфейсов.

Поэтому, Qt стоит рассматривать не столько набор классов для создания GUI, а скорее как полноценный инструментарий классов на все случаи жизни. Этот набор всего (ну или почти всего) что может потребоваться программисту-прикладнику для создания практически любого приложения. Структура библиотеки логично разбита на компоненты, их очень много и с каждой новой версией Qt в них становится все больше и больше полезных классов.

Основных компонента два — QtCore являющий собой ядро библиотеки и QtGui представляющий компоненты графического интерфейса. Как мы в дальнейшем увидим, создаваемый проект всегда имеет при себе два этих компонента (за исключение консольных приложений, в которых обязательную роль играет QtCore).

Ну а далее, в зависимости от потребностей, разработчики вольны использовать все что душе угодно. QtNetwork для работы с сетью, написать свой Torrent-клиент. QtMultimedia для реализации видео-аудио плеера. QtWebEngine для встраивания в свое приложение полноценного браузерного движка. И многое другое.

Стоит так же отметить, что заявленная кроссплатформенность действительно присутствует. Вы можете взять свой код разрабатываемый на одной системе (Windows, MinGW) и скомпилировать ее компилятором другой системы (Linux, GCC) и получить бинарный файл способный запускаться там без особых хлопот. Как показала практика, особые хлопоты начинаются когда приложение становится сильно обвешенным сторонними библиотеками.

Приятным бонусом для веб-разработчиков станет возможность разрабатывать программы не только на C++, но и языке QML, сильно схожим с JavaScript. Это особая ветка развития Qt, направленная на быстрое прототипирование и разработку мобильных приложений.

Ну и конечно же, одной из изюминок Qt является среда разработки Qt Creator. Универсальная и очень удобная среда разработки на Qt, не перегруженная лишним функционалом, .