На хабре то и дело мелькают статьи об успешном опыте использования Qt для разработки под Android, а также под iOS и WP. Статьи наполнены достаточно большим энтузиазмом — ведь это так здорово: пишешь и тестируешь UI на десктопе, а потом просто собираешь с помощью нехитрых команд под Android, iOS, WP, заливаешь в сторы и готово. В этой же статье я хочу поделиться опытом «собирания грабель» преимущественно при разработке под Android.



Qt я использую достаточно давно, начиная с версии 4.1. Не сказать, что я «профессионально» его использую, но опыт был разный — и работы с виджетами и эволюции до версии 5.6.

Некоторые примеры проектов:

  • Пульт управления караоке-центром (Android/iOS)
  • Русско-Татарский словарь с кастомной клавиатурой (Android/iOS/WP), тогда ещё даже API для iOS кастомных клавиатур не было
  • Cоциальная сеть с разными примбамбахами под Android (гео, блютуз, чаты, фотки, профили и т.д.)
  • Приложение для быстрого заказа цветов (Android/iOS/WP)

Кроме того, на Qt написано Android приложение 2gis, на котором вы и можете проверить большинство описанного здесь.

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

Проблема №1


Первое и самое главное на сегодняшний момент: если вам нужно много работать с текстом, вводимым пользователем — не выбирайте Qt/Qml!

Крайне не люблю восклицательные знаки, но тут этот знак на своём месте: вам будет крайне сложно реализовать привычное для пользователей целевой платформы работы с полями ввода, а именно:

  1. Выделение текста
  2. Copy & Paste

Суть проблемы: баг работы с элементом редактирования текста висит аж с 2014 года, отмечен как Important и зарегистрирован пользователем с Silver подпиской, но до сих пор не исправлен. В багтрекере описан обходной путь, но если вы хотите использовать не Quick.Controls а чистый Quick с TextEdit и TextInput — извините.

Возможно кто-то скажет, что я слишком многого хочу и TextEdit/TextInput это базовые компоненты, но, извините меня, отсутствие Copy & Paste в базовых компонентах и отсутствие его реализации в Controls не будут вам доставлять проблем до первого замечания Заказчика.

TextEdit не содержит сигналов работы с указателем, типичных для MouseArea, поэтому попытка реализовать показ контекстого меню через долгое нажатие (PressAndHold в терминах Qml) успехом не увенчается. Кроме того, попытка в лоб обернуть поле ввода в MouseArea подходит лишь для ограниченного числа сценариев, т.к. вам придётся долго и упорно реализовывать выставление курсора между буквами и словами.

Поэтому, остаётся либо лезть в исходники и кастомизировать поле ввода, либо смириться.

Проблема №2


Второе и самое любимое заказчиками приложений, содержащий социализацию: Emoji

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

Узнать, что такое на самом деле Emoji и какова нелёгкая судьба их реализации в различных ОС вам поможет статья в Википедии. По факту же, какие есть варианты:

  1. Использовать шрифт с поддержкой символов Emoji. Используйте FontForge для компиляции Roboto с Emoji!
  2. RichText с заменой символов Emoji на цветные png'шки
  3. Глубокая кастомизация поля ввода (можете посмотреть в исходниках телеграмма для десктопа)

Итого: либо оно выглядит некрасиво (вариант 1), либо глючит (вариант 2), либо требует отличных знаний внутренностей Qt (вариант 3 — а если они у вас есть, вам не стоит труда решить большинство проблем).

P.S. Забавная забавность — не выставляйте никаких inputMethodHints у поля ввода, иначе встроенная Android клавиатура с Emoji (iWinn IME) у вас просто не покажется.

Проблема №3


Третье и самое раздражающее: Мерцание и BlackScreen'ы — ваши лучшие друзья.

Это будет сопровождать вас при загрузке приложения, при попытке выставить windowSoftInputMode в AdjustResize, куски чёрного экрана будут тоже периодически появлятся. Поэтому тестируйте, тестируйте и ещё раз тестируйте на реальных девайсах.

Проблема №4


Четвёртое и самое трудноловимое: Шрифты

Суть проблемы: на разных девайсах каждый год всплывает одно и то же, симптомами похожее на закрытый баг. Вы не узнаете об этом, пока счастливый обладатель андроид-девайсана начнёт жаловаться на то, что шрифт плывёт, ломается, невидимый и т.д. В основном, это китайско-корейские девайсы.

Выход здесь только один — брать исходники Qt и патчить под конкретный GPU.

Проблема №5


Пятое и самое спорное: продвинутые контролы Qml — Camera и иже с ними.

Суть проблемы: частые краши, нехватка функциональности и прочие несоответствия стандартного пользовательского опыта нативных приложений. Лечится это всё очень просто — не стесняйтесь добавлять нативные компоненты (Activity в случае Android) в своё приложение. Да, от этого его кроссплатформенность снизится, а количество кода увеличится, но оно того стоит.

Бонус №1


Первое и самое важное: реальная кроссплатформенность.

Суть: после того, как ребята из SQLite портировали своё детище под WP, а скромный автор сего произведения указал на это ребятам из Qt, в порт Qt для WP был добавлен LocalStorage. Это счастье для всех любителей Qml.

Вы реально можете создавать приложения из одних исходников, реально под кучу платформ, при этом кастомизировать их в нужных местах исходя из возможностей и необходимостей платформы. Декларативный UI и js затягивают настолько сильно и позволяют писать настолько лаконичный код, что возвращаться после него на многословную Java + xml, либо спорный Swift + Storyboard'ы нет никакого желания.

Любые анимации, поддержка кастомных шрифтов, svg — это ли не счастье для мобильного разработчика?

Бонус №2


Второе и самое любимое заказчиками: нестандартность.

Суть: фраза от заказчика, приводящая к желанию убивать — «Сделайте как на айфоне». Теперь это не проблема, везде будет выглядеть примерно одинаково. Да, это нарушение гайдлайнов, да, это нехорошо и никогда так не делайте, но заказчик хочет так и у вас три пути — убедить его, уступить ему или отказаться от него, выбирайте сами.

Кроме того, при достаточном желании можно подхачить исходники платформы, так, как нужно именно вам. Так, в нескольких приложениях мы просто насовсем отключали клавиатуру и писали свою на базе Qt Virtual Keyboard, тогда как встроенные приложения таких возможностей не имели.

Бонус №3


Третье и самое любимое мной: скорость разработки.

Суть: в любом состоянии вы можете спроектировать UI практически любой сложности (исключая особенности взаимодействия с ОС, такие как поля ввода, обработка устройства ввода и т.д.). Если вы сам себе заказчик — то перед вами все дороги открыты.

Резюме


Начиная новый проект стоит прежде всего правильно для себя оценить границы развития этого проекта. Если в нём мало работы с нативными возможностями платформы и много нестандарта — используйте Qt. Если же наоборот — подумайте, сможете ли вы его доработать так, как вам нужно.

Спасибо за внимание! Поделитесь своим опытом использования Qt в разработке мобильных приложений в комментариях.

Upd 31.03.2016 16:53


Спасибо пользователю zsilas за наводку на интересную библиотеку QtOffscreenViews от команды 2gis, которая решает проблемы с вводом текста и показом emoji в полях ввода.

Комментарии (57)


  1. RPG18
    30.03.2016 12:40

    Как разруливаете ситуацию с адоптацией UI под разные размеры экрана и разрешения?


    1. coursar
      30.03.2016 13:06
      +1

      Зависит от проекта. В основном, руководствуемся гайдом от Qt.
      Но были проекты, например, где разработка сначала идёт под десктоп, а потом уже переносится на iOS/Android/WP. Из-за наличия большой кодовой базы просто масштабировали основной экран приложения, сохраняя пропорции (это применимо для планшетов в ландшафтной ориентации).
      Ну и последнее, но не самое красивое решение — это при первоначальной загрузке высчитывать высоту базовой строки исходя из размеров экрана. А из этой базовой высоты уже строится высота всех остальных элементов. Тут нужно отметить, что если вы поддерживаете смарфтоны, то высоту лучше считать из портретной ориентации и не пересчитывать при повороте устройства, иначе в ландшафтной всё будет оч.мелко.



  1. Evengard
    30.03.2016 13:54
    +1

    Так, в нескольких приложениях мы просто насовсем отключали клавиатуру и писали свою на базе Qt Virtual Keyboard

    Это очень сильно пугает. У меня установлена кастомная клавиатура (нестандартная), и что, она работать не будет, и мне будут показывать обычную QWERTY?


    1. coursar
      30.03.2016 14:04
      +2

      Тут всё зависит от задачи, если приложение представляет из себя татарско-русский словарь, пользователю было бы удобнее не искать клавиатуру в плеймаркете/аппсторе/винсторе (тем более, если её там нет), либо добавлять через настройки нужный язык (тем более, если его в настройках нет) а пользоваться приложением сразу с интегрированной клавиатурой.
      Мы на этот счёт проводили исследования на целевой группе, никто не смог найти и скачать кастомную клавиатуру из маркетов без подсказки. Жизнь приложения заканчивалась на фразе "блин, тут ещё чё-то ставить/настраивать надо" в случае с обучалкой, где рассказно, как поставить клавиатуру, либо "блин, а как тут вводить буквы-то" без обучалки.
      Естественнно, если приложение не узко-специализированно, то нужно использовать стандартную клавиатуру.


      1. Evengard
        30.03.2016 16:22

        Фух, а то реально напугали. Если это для настолько специализированных программ, то тогда понятно.


  1. RomanArzumanyan
    30.03.2016 15:56

    Самая сладость начинается тогда, когда нужно использовать разные версии NDK с учётом различных API, которые там представлены. Пытался использовать функции из posix для привязки треда к физическому ядру процессора с учётом cpu affinity — испытал непередаваемое удовольствие.


  1. cccco
    30.03.2016 16:10

    А приходилось ли сталкиваться с ситуацией, когда в приложении под Android, написанном на Qt, есть и foreground сервисы, и активити?


    1. coursar
      30.03.2016 16:36
      +1

      Да, естественнно, а также Broadcast Receiver'ы. С Content Provider'ами (самописными) не приходилось.


  1. aknew
    30.03.2016 16:10
    +1

    не выбирайте Qt/Qml!
    Получается, вы используете QWidget и его потомков? Скажите, как он сейчас работает под android?
    Я когда-то давно, когда порт под андроид еще назывался Necessitas, пытался с ними работать (точнее, просто откомпиллил виндово-убунтовое приложение) и столкнулся с тем что этот путь был совершенно непригоден т.к. виджеты были не адаптированы под тач, например, QTableView и, кажется, скролл имели крайне мелкие размеры скроллбаров, а диалог открытия файлов не ресайзился под экран и был раза этак в 2 больше телефона размером, при этом штатный путь кастомизации через QStyle попросту не срабатывал. В итоге плюнул и постепенно переписал приложение на QML, благо это домашний проект и чего сверхсложного там не было и нет.
    Из сложностей — постоянно натыкаюсь на всяческие мелкие баги в контролах, то у ComboBox'а принципиально нельзя програмно выставить пустую строку (если присвоить comboBox1.currentIndex = индекс пустой строки текст попросту не меняется), то файловый диалог возвращает в винте пути в виде /C:/Users/myFile.txt которые едят не все компоненты qt работающие с путями (конкретно QFile), то еще что. В целом вроде и мелочи, но раздражает, хотя я бы все равно сказал что это классная библиотека.
    Кстати, еще интересный вопрос — есть ли какой-то способ использовать разные элементы для разных платформ из qml? Вариант с подгрузкой через js я знаю, но мне он кажется несколько костыльным


    1. coursar
      30.03.2016 16:41

      Я не использую активно виджеты, поэтому написал именно про QML. Возможно, с QWidget есть способы это решить и потом внедрить решение в QML сцену.
      По поводу второго вопроса не совсем понял, можно использовать Loader с указанием какие конкретно виджеты подгружать. В этом плане полезно смотреть на исходники Quick.Controls, как они там это решают.


      1. aknew
        30.03.2016 16:54

        А что же вы тогда имели в виду под "не выбирайте Qt/Qml"? Я как-то считал что когда речь идет о GUI на Qt, то можно использовать либо QWidget'ы, либо qml, либо же их комбинацию.
        По поводу второго вопроса, да, про loader'ы я забыл, надо будет попробовать. Хотя у меня такой финт может быть и не пройдет — мне надо было загрузить разные меню для андроида и десктопа и хотелось написать что-то вида:
        ApplicationWindow {

        menuBar: Qt.platform.os == "android"? AndroidMenu{}:DesktopMenu{}

        }


        1. coursar
          30.03.2016 17:42
          +1

          Когда я говорил про Не выбирайте Qt/Qml я хотел сказать, что не выбирайте его в качестве технологии для построения UI вашего мобильного приложения на Android если вам нужно очень много работать с текстом привычными для Android-пользователя методами.
          Есть классная игра — VoltAir, сделанная ребятами из Google на базе QtQuick, в ней нет много работы с текстом — вот для этих целей, с моей точки зрения, Qml идеален (с учётом кроссплатформенности). Ради справедливости стоит отметить, если я не ошибаюсь, что ребята из Google правда подхачили немного исходники.


          1. aknew
            30.03.2016 17:47

            Спасибо за разъяснение. Я почему-то подумал что речь о том что вы отказались от qml вообще


    1. zmeykas
      30.03.2016 17:07

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


      1. aknew
        30.03.2016 17:15

        То что можно понятно и я так и делаю, но самый простой способ который я смог найти был загрузка того или иного файла (не в виде плагина, а просто в виде отдельного qml которые отличаются для разных платформ) при помощи js через Qt.createComponent(), и я как раз хотел узнать есть ли более правильный способ.


        1. zmeykas
          30.03.2016 17:23

          Не знаю чем собираются Qt проекты под андроид но в CMake можно указать какую директорию в проект добавить в зависимости от ОС. По директориям распихать компоненты. CMake я правда взял исключительно ради возможности пользоваться CLion. И не уверен стоит ли такой подход затраченого времени в вашем случае.


          1. Zifix
            30.03.2016 17:33

            qmake, и там тоже есть такая возможность. Другое дело, что придется подключать эти директории непосредственно в QML, а вот там препроцессора на импорты нет.


            1. zmeykas
              30.03.2016 17:39

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


              1. Zifix
                30.03.2016 18:01

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


                1. RPG18
                  30.03.2016 18:11

                  Если правильно понял разговор, то в CMake добавляется что-то типа:

                  if(UNIX)
                      install(FILES qml/unix/Foo.qml
                              DESTINATION qml)
                  elseif(WIN32)
                      install(FILES qml/win/Foo.qml
                              DESTINATION qml)
                  endif()


                  1. Zifix
                    30.03.2016 18:26

                    Не лучший вариант на самом деле, если нужно поправить платформоспецифичный компонент, обратно его после тестирования придется руками копировать. Это ладно, один, а если 3-5...


                    1. RPG18
                      30.03.2016 18:36

                      Все изменения должны фиксироваться в системе контроля версии, а для тестеров

                      $ make
                      $ make package

                      на выходе rpm/deb/windows installer


                      1. Zifix
                        30.03.2016 18:40

                        Погодите, вот скопировался платформоспецифичный компонент в папку qml, я его поправил, как он обратно в qml/unix попадет?


                        1. zmeykas
                          30.03.2016 19:02

                          я думаю править нужно исходный компонент, а не тот что скопировался


                          1. Zifix
                            30.03.2016 19:15

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


                1. zmeykas
                  30.03.2016 18:12
                  +1

                  Я имел в виду что-то типа такого: в каждой папке реализован компонент.
                  В основной программе регистрируем кастомный тип:

                  const QUrl MyClass("qrc:/qml/MyClass.qml");
                  qmlRegisterType<MyClass>("com.mycompany.mycomponents", 1, 0, "MyClass");

                  в QML используем:
                  import com.mycompany.mycomponents 1.0
                  
                  MyClass {}

                  файл ресурсов подключается в зависимости от ОС


                  1. Zifix
                    30.03.2016 18:20

                    А в файле ресурсов прописываем алиасы, чтобы нивелировать различие путей, да. На самом деле хорошее решение, кода выйдет чуть меньше.
                    Я говорил именно про подключение напрямую внутри .qml файлов, без регистрации типов в плюсах, там альтернатив Qt.createComponent() нет, но оно не сильно напрягает.


                    1. 1KoT1
                      31.03.2016 08:47

                      Посмотрите в сторону Loader http://doc.qt.io/qt-5/qml-qtquick-loader.html
                      Думаю будет удобнее чем Qt.createComponent().
                      Справедливости ради: Предложение zmeykas подменять файлы при сборке мне нравится больше.


                      1. Zifix
                        31.03.2016 09:13

                        И чем Loader будет удобнее?


                        1. 1KoT1
                          31.03.2016 10:53

                          Тем, что GUI будет описан декларативно.


                          1. Zifix
                            31.03.2016 11:10

                            Он и так описан декларативно, просто подгружаем разные файлы:

                                Component.onCompleted: {
                                    var menuComponent;
                                    if (core.isIOS) {
                                        menuComponent = Qt.createComponent("IosNavigationTabBar.qml");
                                        menu = menuComponent.createObject(panelApplication);
                                    }
                                    else {
                                        menuComponent = Qt.createComponent("AndroidNavigationTabBar.qml");
                                        menu = menuComponent.createObject(mainActionBar);
                                    }
                                }


                            1. Antervis
                              31.03.2016 11:44

                              Аналог этого кода:

                              Loader { source = (core.isIOS) ? "IosNavigationTabBar.qml" : "AndroidNavigationTabBar.qml" }


                              1. Zifix
                                31.03.2016 11:51

                                Вы можете заметить, что у компонентов разные родители, соответственно отображаются они в разных частях экрана.


                                1. Antervis
                                  31.03.2016 12:10

                                  да, этот момент я действительно просмотрел. Можно "засунуть" лоадеры в те места, которым принадлежат загружаемые компоненты, например:

                                  Loader {
                                    source: "IosNavigationTabBar.qml"
                                    active: core.isIOS
                                  }

                                  Просто я считаю использование Qt.createComponent моветоном — оно нарушает декларативность


                                  1. Zifix
                                    31.03.2016 12:13

                                    Можно, но зачем? Почему вы так считаете?


                                    1. Antervis
                                      31.03.2016 12:49
                                      +1

                                      1. В иерархии QML-файла компоненты создаются там же, где они отображаются.
                                      2. Код лаконичнее
                                      3. Свойства объекта задаются прямо в лоадере. createObject же задает свойства создаваемого объекта а. списком, б. по значению

                                      Например, вот здесь: http://doc.qt.io/qt-5/qml-qtquick-loader.html#sourceComponent-prop
                                      достаточно красивый пример правильного, на мой взгляд (и взгляд разработчиков Qt), использования динамической загрузки компонентов


                                      1. Zifix
                                        31.03.2016 13:47

                                        1. Да
                                        2. В простейшем случае — да. В сложном же — работа со свойствами и сигналами компонента в лоадере усложняется.
                                        3. В лоадере по сути тоже списком, просто он обычно представлен по одному выражению в строке ;)

                                        Сложно представить, что на странице документации по Loader будет что-то другое. Вот страница по динамическому созданию от тех же разработчиков.

                                        В целом я с вами согласен, что в простых случаях Loader предпочтительнее.


    1. Antervis
      31.03.2016 10:30
      +1

      в Qt 5 нет возможности вставлять QWidget'ы в QtQuick сцену: stackoverflow.com/questions/13014415/qt5-embed-qwidget-object-in-qml
      Qt уходят от классических виджетов, и не просто так. QML проще в разработке, быстрее в рендеринге, да и кастомизируются проще.


  1. sanja1989
    30.03.2016 16:41

    Только SVG поддерживается не полностью. Есть очень хорошие векторные иконки Oxygen Icons (https://www.archlinux.org/packages/extra/any/oxygen-icons/). Но использовать их нормально не получается…
    Вот цитата из документации (http://doc.qt.io/qt-5/svgrendering.html):
    Qt supports the static features of SVG 1.2 Tiny.
    Так что простая SVG графика отображается без проблем, а что-то сложнее — коверкается.


    1. coursar
      30.03.2016 16:43
      +1

      Согласен, но мы использовали статичные, вместо картинок. Допустим, удобно для стилизованных флагов с градиентом, внедрённых в форму, придуманную дизайнером. Основным бонусом для нас — было избавление от "чудных мнгновений", потраченных на ресайз картинок (хотя imagemagick и скрипты в этом помогает, но потом всё равно вручную их надо отсматривать и находить и исправлять "поковерканные" при ресайзе).
      К слову сказать, нынешние VectorDrawables для Android тоже не идеальны. В Qt с этим проще.


  1. vitaly_KF
    30.03.2016 17:45
    +2

    Спасибо за статью. Я в свое время столкнулся тоже с некоторыми проблемами, что привело к появлению собственных велосипедов. Может они будут полезны и Вам в чем-то:

    • https://github.com/kafeg/qtrest — полноценный REST клиент, который умеет автоматически маппить JSON/XML в наследника QAbstractListModel, обрабатывать fetchMore и canFetchMore для пагинации, умеет передавать параметры сортировки и фильтрации и прочие нужные фишки. Имеет интерфейс из C++ и QML. Из коробки умеет работать с Yii2 REST API и Django REST Framework (ну как умеет, по их лекалам сделан =) ). Пока в полубете, много еще чего нужно сделать.
    • https://github.com/kafeg/adctl — QtAdMob и Google Play Game Services для Qml.

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


    1. coursar
      30.03.2016 18:07

      Неплохо, а почему не строить работу с REST через WorkerScript и обычный Ajax? Если там возвращается JSON — то это очень просто и удобно. Ну и есть ListModel sync (если не нужны всякие фишки с сортировкой, fetchMore и т.д., которыми можно нагрузить разработчика серверной части).


      1. vitaly_KF
        30.03.2016 18:19

        Хотелось один раз сделать все полноценно. Почти в каждом проекте работающем с API есть стандартная потребность в получении данных и их сортировке/фильтрации/подгрузке, так и в отправке POST/PUT запросов. Плюс мне хотелось иметь доступ к моделям как из QML так и из C++ и располагать всеми средствами для предобработки данных из C++.
        На JS можно было бы реализовать такую логику, но мне кажется код получился бы гораздо сложнее.
        Сейчас, если Вы обратили внимание в репозитории описан сложный метод использования библиотеки — через создание производного класса. На самом же деле я планирую еще создать какой-нибудь простой QML-компонент для модели, чтобы ему модно было лишь передать параметр и показать API-метод из которого стоит брать данные. В этом случае программисту нужно будет лишь унаследовать и реализовать класс работы со своим API.


  1. Harrix
    31.03.2016 06:05

    А как вы решаете момент с черным экраном при запуске Qt Quick приложения на Android?


    1. Zifix
      31.03.2016 09:02

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


      1. Zifix
        31.03.2016 09:40
        +1

        А момент этот возникает из-за бага.


      1. Harrix
        31.03.2016 10:04

        Но как то же тот же 2Гис решило проблему… У них при запуске программы черного экрана нет.


        1. Zifix
          31.03.2016 10:16

          У них Qt патченное.


        1. zsilas
          31.03.2016 14:25
          +2

          Можно использовать QSplashScreen и закрывать его по сигналу из QML, например когда нужные части UI прогрузились


    1. coursar
      31.03.2016 10:29
      +1

      Мы используем плавную анимацию opacity контейнера с контентом и фоновым цветом от 0 до 1. В итоге эффект следующий (он не совсем решает проблему, но немного улучшает поведение приложения): чёрный экран и плавное появление интерфейса вашего приложения.


  1. Antervis
    31.03.2016 10:58
    +2

    Самое важное не написали: модуль QtLocation очень скуден для реального использования. По факту, подходит для демо тулзы с тайловой картой osm/here/mapbox, и эта карта даже не поддерживает вращения (bearing). Можно написать геоплагин, предоставляющий тайлы, это в принципе несложно. Но если же вы хотите написать свою векторную карту на основе QML Map, будьте готовы, что от оригинального кода QtLocation у вас останутся лишь формулы пересчета пикселей сцены в координаты.


    1. coursar
      31.03.2016 11:43
      +1

      Спасибо за разъяснения. Опыта работы как такового под Android/iOS/WP с QtLocation не было. Когда только начинал интегрироваться с "железными фичами", такими как камера — понял, что оно далеко от идеала, в связи с чем работу с сенсорами, гео, блютуз, камерой и прочим строю исключительно на базе нативных компонентов и уже при необходимости передаю результат обратно в Qt.


      Поделитесь, пожалуйста, опытом сравнения с нативными аналогами.


  1. zsilas
    31.03.2016 12:05
    +2

    По первой проблеме есть вполне себе готовое решение для андроида.
    Можно использовать обертки над нативными полями ввода.
    https://gitlab.com/2gisqtandroid/qtandroidextensions/tree/master/QtOffscreenViews


    1. coursar
      31.03.2016 16:48

      Попробовал, да, действительно, проблема с тестом и Emoji решается. Насколько большой опыт использования у вас этой компоненты? Есть ли какие-то камни и т.д.?

      И не знаете ли, почему они не используют это решение в своём Android приложении?


      1. Zifix
        31.03.2016 16:51

        Посмотрите в профиль


      1. zsilas
        31.03.2016 17:28
        +2

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