[CppCon 2017] Ларс Кнолл: C++ фреймворк Qt: История, Настоящее и Будущее

в 18:38, , рубрики: c++, cppcon, QML, qt, qt quick

Содержание цикла обзора выступлений CppCon 2017:

Обзор выступления Ларса Кнолла (Lars Knoll), являющегося техническим директором Qt Company. Не ждите от этого выступления слишком многого. В квадратных скобках курсивом мои примечания.

Спасибо за возможность немного рассказать о Qt. Это C++ фреймворк. Его принципы и философия немного отличаются от тех, которые вам знакомы по стандартной библиотеке. [Вопрос к залу] Просто для информации, многие ли из вас знают Qt и использовали его раньше? Вау! Спасибо, здорово! Это фантастика! Тогда я буду рассказывать о вещах, которые вы вероятно уже знаете.

Что такое Qt?

Возможно, это самый всеобъемлющий C++ фреймворк. Но это не только фреймворк, это также разнообразные инструменты, которые помогают разрабатывать embedded-устройства, UI-технология Qt Quick, не относящаяся к C++, но интегрируемая с ним.

Две лицензии: коммерческая и LGPLv3/GPLv3. Это открытый проект.

Два продукта:

  • Qt for Application Development (Desktop & Mobile Platforms: Android, Linux, Windows, Mac, iOS)
  • Qt for Device Creation (Embedded platforms: Android, Linux, Windows,QNX, VxWorks, Green Hills Software (IOT, интернет вещей))

Qt for Application Development

Qt модули

В основе находятся неотъемлемые библиотеки. Самая главная — Core, содержащая основные классы, I/O, работу с файлами и т.д. Библиотека GUI — основа графического интерфейса. И много других.

Qt for Device Creation

Qt embedded

Qt Creator

Кроссплатформенная среда разработки для настольных, мобильных и встраиваемых систем. Многие используют ее для программирования на чистом C++, без Qt. Поддерживает интеграцию различных инструментов (профилировщики, отладчики...), автокомплит, VCS...

Qt Creator
Раннее обнаружение ошибок с помощью Qt Creator и CLang static analyzer

История

Перенесемся на 26 лет назад. Студенты Haarvard Nord и Eirik Chambe-Eng задумались над новым проектом. В то время они занимались разработкой GUI для системы, которая работала на Unix, Macintosh и Windows. Это было трудно. Летом 1990 они решили, что им нужна объектно-ориентированная система отображения.

В 1993 было разработано первое графическое ядро

early Qt

Эта версия называлась Quasar. Тогда не существовало пространств имен. Motif (библиотека элементов интерфейса и набор спецификаций для разработки графических интерфейсов под X Window System) имела свой префикс. Поэтому был добавлен префикс "Q", который исполнял роль пространства имен. Сейчас от той версии сохранилось многое. Остался QObject — центральная часть, реализующая механизм сигналов/слотов. А также QEvent, QFont, QPainter, QColor.

В 1994 они убедили своих жен поддержать их финансово пару лет, и основали компанию Trolltech.

Trolltech Site
Ранняя версия сайта Trolltech

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

1996: Qt 1.0

Работал полностью без шаблонов. Поэтому было несколько специализированных списков для указателей, целых чисел и пр. Поддерживались Windows 95/NT и UNIX/X11. Версия для UNIX была с открытым кодом, так как маленькой компании нужно было как-то распространить свой продукт.

New Project: Kool Desktop Environment (KDE)

В 1997 Маттиас Эттрих (известный за свой вклад в проект KDE) решил использовать Qt для создания KDE. Вероятно это и стало причиной по которой Qt "взлетел".

first_kde

1999: Qt 2.0

Был выпущен под лицензией GPL. Появилась поддержка юникода. Проекту был предоставлен венчурный капитал. Количество сотрудников за год увеличилась с 5 до 50.

Были разработаны основные виджеты, а также слои, обеспечивающие "гибкий" интерфейс. Но людям не хотелось писать код для этого. Тогда появился Qt Designer.

qt_designer
первая версия

В это время я перешел на работу в Trolltech [И поэтому автор стал далее использовать местоимение "мы"]

2001: Qt 3

Мы заменили explicit sharing на implicit sharing для строк. У людей появилась куча проблем со строками. Тогда мы решили оставить implicit sharing, но создавать новый внутренний экземпляр, когда строка меняется (copy-on-write) [далее чуть подробнее].

Стали использовать больше шаблонов, C++98. Появился qobject_cast<> (аналог dynamic_cast для QObject, но не использующий RTTI). Открыты исходники для Mac.

2005: Qt 4

Тщательно пересмотрели шаблонные и вспомогательные классы. Перешли от хранения указателей на значения в контейнерах к хранению самих значений. Implicit sharing контейнеры стали использовать атомарный подсчет ссылок. Открыты исходники для Windows. Для Windows это было сделано в последнюю очередь, потому что нам был нужен доход и покупатели чтобы выжить.

Nokia приобретает Trolltech

Nokia была заинтересована в общем API для их платформ (S40, Symbian & Maemo/MeeGo). Были получены огромные инвестиции в Qt. Мы долгое время хотели разработать кроссплатформенное IDE, но не было средств. Руководство предлагало Eclipse, но она не очень хороша для C++. C Nokia наше желание стало возможным и был создан Qt Creator. А также Qt Quick. Еще мы стали работать над интеграцией движка WebKit. Nokia сменила лицензию с GPL на LGPL, что сделало фреймворк еще более свободным.

В 2012 мы разошлись с Nokia.

2011/2012 Qt 5

Digia приобрела Qt.

Портировать на новые платформы было трудно, поэтому добавили слой абстракции. Хорошо поработали над графическим интерфейсом, он перестал быть статичным. Например, это видно по окошку Dock Widget во время перемещения.

2016: Qt Company отделилась от Digia

Qt Company сегодня

250 сотрудников, годовой доход 32 миллиона евро. Около миллиона активных пользователей.

Qt сейчас

Наши цели:

  • Поддержка старого кода
  • Интуитивность
  • Самодокументированность
  • API, простое для изучения и использования
  • Производительность

Сохранение простоты

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

Реализация

[Поверхностно рассказывается про основы QObject, Сигналы/Слоты, moc, про которые написано в любом руководстве, пропустил]

Implicitly shared

Подробнее: Implicitly shared

Многие классы реализованы примерно так:

class QFont
{
    void setPointerSize(int pt)
    {
        if (d->refCount != 1)
            detach();
        d->pointSize = pt;
    }
private:
    detach();
    QFontPrivate *d;
};

class QFontPrivate
{
    QBasicAtomicInt refCount;
    int pointSize = -1;
    int weight = QFont::Normal;
};

Это позволило нам быть более свободными при добавлении и удалении членов класса. При изменении объекта создается копия внутренних данных. Достоинства такого подхода:

  • Объекты ведут себя почти как примитивные типы
  • Простое и быстрое копирование объекта
  • Объект может быть передан по значению
  • Потокобезопасно

Недостатки:

  • Небольшое ухудшение производительности из-за атомарного счетчика
  • Небольшое изменение семантики итерирования
  • У Range-for циклов могут быть проблемы:

for(auto c : qvector) //Отделяется (detached) если вектор не константный
for(auto c : qAsConst(qvector)) //Решение

[В первой строке detach действительно вызывается, но создание внутренней копии произойдет только если счетчик будет больше единицы, например:]

QVector<int> v1 = { 1, 2, 3 };
QVector<int> v2 = v1; //Копирования внутренних данных не произойдет, просто v1 и v2 будут ссылаться на одну и ту же копию
for (auto c : v1) //А вот здесь произойдет, при вызове v1.begin()

Заполнение недостающего в стандартной библиотеке:

  • QString с поддержкой юникода, который C++ нормально не поддерживает.
  • QLocale
  • QDate/QTime/QDateTime/QTimeZone
  • QAtomic и потоки. Реализованы до C++11
  • Работа с файловой системой, I/O, сетью
  • Графика

Qt Quick

[Самые-самые основы QML, ничего нового. Пропустил]

Будущие релизы

  • Qt 5.9 — текущий релиз (long term supported — 3 года)
  • Qt 5.9.2 — скоро
  • Qt 5.10 — скоро бета, релиз в ноябре
  • Qt 5.11 — май 2018
  • Qt 5.12 — ноябрь 2018 (возможный кандидат следующего long term supported)

Графика

Включение различных графических API в Qt Scene (OpenGL, Vulkan, Metal, Direct3D, Software Rasterization)

Плановая работа

  • Улучшение производительности
  • Распознавание речи (цифровой помощник?)
  • AR/VR
  • Инструменты IDE (рефакторинг, workflow)

C++14 & 17

Мы используем C++11 в той мере, в которой позволяет VS2013. Мы бы хотели использовать:

  • if constexpr
  • Initializers в if/switch
  • Structured bindings
  • Overaligned data

Уже используем __has_include, [[deprecated]], [[fallthrough]], [[nodiscard]]. Добавили QStringView.

C++20

Мог бы стать очень интересным для Qt: концепты, модули, рефлексия (может быть даже удалось бы избавиться от moc когда-нибудь в будущем).

Вопросы и ответы

Что вы скажете о безопасности Qt?

Конечно мы работаем над этим, тратим много времени, выпускаем патчи, апдейты. Наш security mailing list достаточно небольшой.

Как произносится: "кьютИ" или "кьЮт" [очень мягкая "т" в обоих случаях]?

Хороший вопрос! В нашей компании и в тех которые работают с нами используется "кьЮт", хотя в США преимущественно "кьютИ". [А как у вас? Добавил голосовалку]

Программирование на Qt отличается от программирования на C++. Что вы думаете о дублировании функционала — например QVector и многого другого? Планируете объединить или что?

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

Сейчас в Qt используются сырые владеющие указатели (raw owning pointers). Не пора ли их заменить на умные? Сейчас объект с умным указателем нельзя передать в Qt, потому что у него появится родитель.

Это очень сложно. И сломается весь старый код.

Если вашкод опенсорсный, то откуда доход?

От продаж коммерческой версии.

Почему бы к QObject и производным классам не добавить конструктор перемещения? С конструктором копирования это понятно [почему нет конструктора копирования].

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

Вы проводили оценку быстродействия модели copy-on-write для строк по сравнению с простым копированием?

Для коротких строк копирование быстрее. Скоро выйдет обновление, в котором будет реализован подобный механизм для коротких строк.

Как насчет поддержки других графических API?

Если мы говорим о 3D API, типа Apple Metal, Vulkan, Direct 3D 12, то это сложно.

Автор: Fil

Источник

Поделиться

* - обязательные к заполнению поля