Как стать автором
Обновить

Комментарии 37

Неплохая статья, спасибо.
Но Qt как по мне — рискованная затея. Ни нативных виджетов, ни нативных UX-паттернов, ни особо интеграции с Android-компонентами как я понимаю. Хотя к своему стыду я очень мало о нем знаю таких технических деталей.
Вообщем-то основных вопросов пока два — есть ли хоть какая-то интеграция с джавой и как оно дружит с не-ARM архитектурами (x86/MIPS)?
Насчёт интеграции скажу точно, что можно через QAndroidJniEnvironment и QAndroidJniObject получать доступ к нативным java-классам Android'a (похоже на рефлексию в Java). Поддержка x86 есть
Раз уж вы упомянули про рефлексию, можете сказать как обстоят дела с производительностью QAndroidJni* классов?
к сожалению, нет, потому что в Qt эти классы не доводилось использовать
Интересует сравнение QT и Xamarin Forms. Кто то может написать?
На QT не писал, Xamarin.Forms смотрел. Могу высказать общие тезисы:

1) И то и другое появилось недавно (Qt Mobile — молодой продукт) и как следствие имеет множество косяков.
2) QT в отличии от Xamarin.Forms есть на Windows 8 (Windows Store Apps) и на всех основных десктопах, Forms только на iOS, Android, WP8
3) Xamarin.Forms использует внутри себя нативные контролы и относительно легко расширяется ими. (Как я понял в QT это делается через «рефлексию» поправьте меня, кто знает)
4) Разработчиков на Qt больше чем разработчиков на Xamarin.Forms.

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

ЗЫ. По крайней мере на iOS, только ядро 2Гис написано на Qt, интерфейсы написаны нативно (в том понимании, что через системные функции).
Хм, а откуда информация про Qt в ядре? Вот тут просто был разговор, что как раз нет.
От разработчиков. Они портировали Qt для iOS для этих целей (а перед этим допилили чью-то наработку Qt под Android, тогда ещё не было ни того, ни другого). Вообще, подробности были на этом докладе, но видео, к сожалению, нет.
Xamarin Forms — это абстракция над нативными виджетами каждой платформы. В Qt — свои виджеты, которые к нативным виджетам платформ не имеют никакого отношения. Если коротко.
Разница между Qt5 и Qt4 — 8 лет, сменилась мажорная версия и практически вся архитектура была переделана с заделом на будущую кроссплатформенность (в т.ч. абстракцию от железа). Поддержка Android/iOS сырая потому что на направлениях работает мало людей и цели у них пока лишь бизнес-ориентированные, до полноценной разработке мобильных приложений на Qt ещё очень далеко (дальше, чем кажется).

Насчёт ловли ошибок — тут проблем меньше, чем могло бы быть, так как средства qDebug работают хорошо и в некоторых языках только так и отлаживают. Но для C++ ещё доступен GDB с возможность анализа дампа упавшего приложения, в том чилсе можно с лёгкостью отследить баги в QtCore и найти место в исходниках Qt, пофиксить, пересобрать… Тут как обычно, хоть и очень далеко от удобств нативных средств (xcode/ms vs/...).

Суть: мы можем использовать только одно OpenGL-окно
Они об этом частенько писали, но вроде как можно использоваться несколько OGL-виджетов в одном окне, я не копал эту тему, просто как-то раз задал вопрос и даже сам автор порта Qt не смог чётко ответить. Сыро, что уж тут.

>Qt открыт и бесплатен для некоммерческого использования

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

Так же Qt можно использовать под платной коммерческой лицезией, что включает в себя классы отсутствующие в LGPL версии.
Можете прояснить одну ситуацию, может я что-то не так понимаю? В сети нигде толком в двух словах объяснения не нашел.
Краем уха я где-то слышал, что Apple принимает для iOS приложения только со статически слинкованными библиотеками (у Google и Microsoft такого маразма нет?). А LGPL, в свою очередь, при статической линковке библиотек обязывает раскрывать исходники использующего их кода. Я ничего не напутал? И что насчет остальных платформ, Android и WP?
LGPL не требует выкладывания исходников слинкованного статически кода, зато требует предоставления пользователю возможности самостоятельной линковки со статическими библиотеками под LGPL. Распространяйте в архиве с приложением ваши obj-файлы и краткий readme по самостоятельной линковке (необязательно, но большой плюс в карму) и лицензия вам не страшна.
Т.е. размер пакета и так немаленького приложения увеличивается еще в ~<=2 раза?
Только непонятно, если я не изменял код библиотек, зачем мне распространять obj-файлы, если пользователь может сам скачать оригиналы исходников/бинарников и слинковать их как ему угодно? Да и если даже изменял — выложить измененные исходники в публичный доступ и сослаться на них в пакете/приложении, не?
Нужны не obj-файлы билиотеки, а obj-файлы, собранные из вашего проприетарного кода, чтобы можно было собрать себе версию вашего приложения со своей версией библиотеки.
Ах, вон что, теперь понятно…
Тогда такой вопрос: а что, если я буду распространять статически слинкованное приложение без obj-файлов и одновременно с этим предоставлять возможность скачать эти obj-файлы или скачать это же приложение, но слинкованное динамически, так прокатит? :)))

И таки насчет Apple, действительно ли у них есть такое требование и что насчет других платформ, если вы в курсе?

Может кто-то еще в курсе? На Хабре же точно кто-то должен знать, правда же? Кто-нибудь? Нет? Ну, пазязя… )
Тогда такой вопрос: а что, если я буду распространять статически слинкованное приложение без obj-файлов и одновременно с этим предоставлять возможность скачать эти obj-файлы или скачать это же приложение, но слинкованное динамически, так прокатит? :)))

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

Собственно, именно так большинство GPL/LGPL и распространяется: линукс с окружением вы обычно получаете в бинарниках в виде livecd с инстяллятором, и для уменьшения размеров там даже мануалов обычно нет, не то, чтобы исходников. Но исходники вы всегда можете скачать, причём вместе с изменением — это src-пакеты дистрибутива (srpm, source deb и в таком духе) или отдельно набор патчей, которые разработчик наложил на оригинальные пакеты или накладываются при сборке на машине пользователя (так сделано в gentoo).
Очень забавно было читать фразу «Что ж, безусловно не стоит говорить о том, что ни один кроссплатформенный интсрументарий не сравнится с нативом.» ))) Я конечно понял, что в данном случае вы подразумевали использование стандартных для платформы элементов GUI. Но обычно под «нативом» подразумевают как раз нативный код (в противопоставление управляемым и скриптовым языкам), т.е. в первую очередь C/C++. А соответственно Java — это уже не «натив», даже на Андроиде. В общем если вырвать вашу фразу из контекста, то от неё может возникнуть шизофрения. )))

Если же говорить о «нативе» в вашем значение, то соглашусь, что нативные контролы практически всегда смотрятся приятнее. Как раз поэтому (ну и плюс потому что она использует просто C++, а не модифицированного мутанта) я и предпочитаю библиотечку wxWidgets вместо Qt, т.к. она работает только с нативными контролами на всех платформах. Но как следствие этого, версии под Андроид у wxWidget нет, т.к. хотя ndk и позволяет писать чисто нативные (в обычном смысле) приложения, но доступа к стандартному GUI не даёт. Ну а отсутствие поддержки лидирующей на рынке платформы автоматом обозначает отсутствие поддержки мобильной разработки на wxWidgets. К большому сожалению, т.к. до занятия Андроидом лидирующих позиций, это был пожалуй самый эффективный кроссплатформенный инструмент.

А вот если не стесняться применения GUI собственной прорисовки, то тогда спектр инструментов кроссплатформенной разработки становится заметно более широким (собственно подходит любая библиотека рисующая в итоге через opengl es). Хотя если говорить о нативном коде, то такое сочетание применяется преимущественно в играх и т.п. проектах.
Хм, честно говоря, не знал, что под «нативом» в первую очередь подразумевают именно нативный C/C++ код. Всегда считал, что натив — это просто использование SDK соответствующей платформы без дополнительных слоёв сверху в виде кроссплатформенных фреймворков и библиотек. Спасибо, учту, буду точнее в определениях.

С последним высказыванием абсолютно согласен. Более того, иногда можно увидеть, как на том же Unity3D (а в нём нативных контролов нет) делают не только игры, прикручивают, например, работу с БД, MVC и тд и тп. Хотя огромная редкость, конечно.
Qt достаточно часто обновляется, что, с одной стороны, хорошо, но, с другой стороны, порой делает разработку ночным кошмаром. Происходит это потому, что новые версии не имеют совместимости со своими предшественниками, часть функционала которых в лучшем случае устаревает, в худшем — становится более недоступной.

Простите, что? 5.3 не совместим с 5.2? Вы точно в этом уверены?
Несовместимость есть только между мажорными версиями, Четверка жила лет 8, пятерка только начала свой путь.
о мажорных версиях речь как раз и шла
ну если для вас 8 лет — это очень часто, то я даже не знаю что сказать. Без таких обновлений мы бы погрязли в legacy-коде и идеях 20-летней давности.
ну и плюс кому действительно надо (например огромная система на четверке, которую писали 20 человеколет) — просто остаются на четверке. Legacy — оно такое
Ваше мнение услышано. Буду обращать внимание на такие детали.
Я не стал сильно вчитываться и читал больше по диагонали, но вкратце — я бы такой код не принял и отправил бы переделывать с нуля. Возможно еще много бы при этом сказал не очень красивых слов.
Ниже то, что совсем уж цепануло глаз.

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

Это наверно один из худших вариантов, как можно работать с кумлем

Button {
width: mainWindow.width / 2.5
height: mainWindow.height / 10
x: 0
y: mainWindow.height — height
}

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

font.pixelSize: (mainWindow.width>mainWindow.height)? parent.height/1.75: parent.height / 2.5

не стоит ради такой мелочи городить external reference

style: ButtonStyle {
background: ButtonBackground {}
label: ButtonLabel { text: «Тест» }
}

Конечно, зачем нам text у самой кнопки, к чему бы он нам

class Backend: public QQuickItem

Ни к чему, можно просто QObject. Тем более что все равно он идет как контекстное свойство, даже не как кумльный элемент

mainWindow = engine.rootObjects().value(0);
lvList = mainWindow->findChild<QObject*>(«lvList»);
btnRequest = mainWindow->findChild<QObject*>(«btnRequest»);

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

Это наверно один из худших вариантов, как можно работать с кумлем

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

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

Прислушаюсь здесь. Буду использовать анкоры в будущем. Изначально думал, что с расчётами размеров относительно главного окна будет наглядней и удобней.

не стоит ради такой мелочи городить external reference

как следует поступить лучше в данном случае?

Конечно, зачем нам text у самой кнопки, к чему бы он нам

Опять-таки, видеть подпись у label логичней, имхо. Если так критично расположение одной строчки с text, аргументируйте, пожалуйста

Ни к чему, можно просто QObject. Тем более что все равно он идет как контекстное свойство, даже не как кумльный элемент

Можно, опять-таки, не вижу здесь критичности.

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

Всю логику UI порой в принципе невозможно перенести в QML. В зависимости от работы в бэкенде, может и меняться UI. Но действительно здравое решение делать функции, изменяющие параметры элементов UI в самом QML. Я правильно понял вашу мысль? Подобное решение использовал, т.к. изначально хотел использовать знакомые по разработке в Android идиомы, там же в самой вёрстке логика не прописывается, верно (если не создавать кастомные классы для UI). Впрочем, повторюсь, используешь инструментарий — используй по его гайдлайнам.

Ещё раз спасибо за развёрнутый комментарий
как следует поступить лучше в данном случае?

очень много разных вариантов. Начиная от проперти у кнопки (к которой из стиля есть доступ через control) и заканчивая своим хранилищем подобных переменных (например на плюсах через q_property).
Опять-таки, видеть подпись у label логичней, имхо. Если так критично расположение одной строчки с text, аргументируйте, пожалуйста

Ну если логичнее видеть текст кнопки в описании ее стиля — то я даже не знаю что сказать. То, что описывается через style — это именно стилизация, то есть то, как выглядит кнопка. А ее логика (текст в данном случае тоже часть логики) — это сама кнопка.
Можно, опять-таки, не вижу здесь критичности.

Ну это просто как микроскоп для забивания гвоздей. QQuickItem — визуальный элемент.
Всю логику UI порой в принципе невозможно перенести в QML. В зависимости от работы в бэкенде, может и меняться UI.

Очень даже возможно. Обычно делается через кучу сигналов в бекенде, а в кумле эти сигналы слушаются и делаются нужные вещи. Только сигналы конечно не вида paintButtonInColor(), а вида someActionAllowed() и кумль уже сам там разбирается что ему надо сделать при этом. В идеале бекенд не должен знать вообще ничего о том, как устроен UI, иначе можно однажды упереться в абсолютную неподдерживаемость такого кода (когда там будут сотни зависимостей между бекендом и фронтендом и даже небольшое изменение фронтенда приведет к куче багов).
Подобное решение использовал, т.к. изначально хотел использовать знакомые по разработке в Android идиомы, там же в самой вёрстке логика не прописывается, верно (если не создавать кастомные классы для UI).

Было бы странно в андроиде использовать привычки из Qt, а в хаскелле привычки из паскаля. Все инструменты очень разные
Очень даже возможно. Обычно делается через кучу сигналов в бекенде, а в кумле эти сигналы слушаются и делаются нужные вещи. Только сигналы конечно не вида paintButtonInColor(), а вида someActionAllowed() и кумль уже сам там разбирается что ему надо сделать при этом. В идеале бекенд не должен знать вообще ничего о том, как устроен UI, иначе можно однажды упереться в абсолютную неподдерживаемость такого кода (когда там будут сотни зависимостей между бекендом и фронтендом и даже небольшое изменение фронтенда приведет к куче багов).


Здравая рекомендация, благодарю. Такая идея мне почему-то в голову не пришла: действительно будет намного удобней, чтобы не заморачиваться с огромным числом зависимостей между бэкендом и QML. Плюс в теории таким образом можно удобно разделить разработку приложения на 2 независимые части для фронтендщика и бэкендщика. В очередной раз убеждаюсь в хорошей гибкости Qt.
Почему не работали с сетью через Javascript? С этим спокойно справляется асинхронный XMLHttpRequest. И распарсеный с помошью JSON.parse() ответ сразу можно использовать в качестве модели.
JavaScript не использовал, потому что хотел больше погрузиться в сам Qt и было желание писать на C++. Предложенный вами способ возьму на заметку, спасибо.
Откуда идет это желание сделать логику на кумле, который для это не предназначен? Плюсы же удобнее на порядок
Плюсы удобней (особенно если всегда на них писал). Но если, например, человеку из веб-разработки привычней JS, то почему бы не использовать этот язык для логики? Самое главное, что такой выбор есть.
к сожалению, в абсолютном большинстве случаев — перенос логики в кумль приводит к сильному уменьшению поддерживаемости и расширяемости кода.
Хотя наверно где-то есть те самые 2% случаев когда все ок, но я их еще не встречал. А вот случаев, когда хватаешься за голову от увиденного и понимаешь что некоторые вещи дешевле переписать с нуля, чем пытаться впихнуть новую фичу — это навидался.
На Javascript можно написать быстрее, короче и соответственно проще. Тем более если дело касается JSON и http-запросов.
сделал дополнения, спасибо за активное участие в обсуждении, за информативные комментарии (особенно Xlab, IGHOR), за дополнительные комментарии и разъяснения в лс — tass, V0VaN.
Что касается нативного Web-виджета для Андроида, то у нас в 2ГИС он есть, правда, пока в альфа-состоянии, так как до использования в боевых приложениях дело не дошло. Зато там же есть поддержка настоящего EditText-а Android. Библиотека совместима с нашим портом Qt 4.8 и обычным Qt 5.3.

gitorious.org/qtandroidoffscreenviews

Писать вопросы можно сюда:

groups.google.com/forum/#!forum/qtandroidviews
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории