Qt

Qt vs wxWidgets личный опыт

February 28th, 2011 Begemot

Меня тут спросили, спросили – отвечаю. В кратце про Qt vs wxWidgets после некоторого опыта, очень в кратце.

 

Про Qt:

1. На Qt писать быстрее и проще (субьективно и смотря что)

2. Написанное под виндо в течении 3 месяцев запускается на макоси после часа работы.

3. Приложения не родные

4. Приложения здоровые.

 

Про wxWidgets:

1. Писать вполне нормально, хотя может и не так гладко как на Qt

2. Результат выглядит роднее

3. Бинарников по паре сотен килобайт не получается, но и не десятки метров как у Qt.

4. Запуск под макосом – требует гораздо большего количества нервов, времени и напильников.

 

Для этой программы я после 10 дней на вх, выбрал Qt (совсем его тогда не зная), и не пожалел. Для своих Clipdiary и Flashnote я все таки считаю что wx не плох, хотя следует признать что первая программа уже продается под МакОС, а вторая и третья только в далекой перспективе:)

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

А еще, учитывая последний маневр Нокии, есть вероятность что развитие Qt тормознется, об этом стоит тоже думать….


О правильных контейнерах, методах и алгоритмах

January 27th, 2011 Begemot

Довелось мне тут недавно портировать один код, считающий dog inbreeding coefficient, с C# на С++/Qt. Код портировался легко, фактически 1 в 1, за исключением того что стеки в Qt ведут себя немного не так как в шарпе, но это решилось. Через некоторое время обнаружилось, что на больших родословных код работает непозволительно медленно, в шарповской версии, что интересно, проблем не было, пришлось оптимизировать.

Шаг первый – правильные контейнеры.

Код использовал списки, при портировании я их и заменил на QList. Но в принципе списки не самый быстрый контейнер для простых операций. Первое что я сделал заменил на QVector. Автозаменой, получил прирост в 30%.

Шаг второй – правильные методы доступа.

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

For read-only access, an alternative syntax is to use at():

at() can be faster than operator[](), because it never causes a deep copy to occur.

У нас в контейнере хранились просто int’ы, ничего более сложного, поэтому чудес я не ожидал. Но произошло чудо:)

Замена всего одной строчки в коде вида

Q_FOREACH(QList<int> pf, paths_father)

{

Q_FOREACH(QList<int> pm, paths_mother)

{

if (pf[0] != pm[0]) continue;

Дала прирост на порядок для количества путей родителей XXK на XK, и в сотню раз (!) для количества порядка 220K на 30К. Сказка.

И наконец, финальный аккорд – алгоритмы.

К сожалению, таким образом удалось улучшить только второе проблемное место. А построение путей по прежнему было медленным. Пришлось найти другой алгоритм и все переписать. Стало почти мгновенно, особенно после добавления кэширования:) Как бонус считать стало более точно, так как оригинальный алгоритм игнорировал один параметр.

В общем, правильные вещи – рулят.


Mac Style

August 18th, 2010 Begemot

А вот и пошли грабли с Qt look and feel in Mac OS, в принципе то было заранее известно, но все равно плохо. Описал проблему на rsdn


Тащим wxWidgets в Qt

July 5th, 2010 Begemot

К хорошему быстро привыкаешь. Привык и я к wxCHECK*, тяжко в Qt теперь – там такого нету. Мучился, я мучился и решил – а почему бы и нет?

В итоге добавил себе

//------------------------------------------------------------------------------------------------------------------
// macros ported from wxWidgets

/*
    wxCHECK macros always check their conditions, setting debug level to 0 only
    makes them silent in case of failure, otherwise -- including at default
    debug level 1 -- they call the assert handler if the condition is false

    They are supposed to be used only in invalid situation: for example, an
    invalid parameter (e.g. a NULL pointer) is passed to a function. Instead of
    dereferencing it and causing core dump the function might use

        wxCHECK_RET( p != NULL, "pointer can't be NULL" )
*/


// the generic macro: takes the condition to check, the statement to be execute
// in case the condition is false and the message to pass to the assert handler
#define wxCHECK2_MSG(cond, op, msg)                                       \
    if ( cond )                                                           \
    {}                                                                    \
    else                                                                  \
    {                                                                     \
       Q_ASSERT_X(cond, "", msg);                                         \
       op;                                                                \
    }                                                                     \
    struct wxDummyCheckStruct /* just to force a semicolon */


// check which returns with the specified return code if the condition fails
#define wxCHECK_MSG(cond, rc, msg)   wxCHECK2_MSG(cond, return rc, msg)

// check that expression is true, "return" if not (also FAILs in debug mode)
#define wxCHECK(cond, rc)            wxCHECK_MSG(cond, rc, (const char*)NULL)

// check that expression is true, perform op if not
#define wxCHECK2(cond, op)           wxCHECK2_MSG(cond, op, (const char*)NULL)

// special form of wxCHECK2: as wxCHECK, but for use in void functions
//
// NB: there is only one form (with msg parameter) and it's intentional:
//     there is no other way to tell the caller what exactly went wrong
//     from the void function (of course, the function shouldn't be void
//     to begin with...)
#define wxCHECK_RET(cond, msg)       wxCHECK2_MSG(cond, return, msg)

//------------------------------------------------------------------------------------------------------------------

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


QSqlRelationalTableModel – отстой, и другие грабли

May 31st, 2010 Begemot

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

Может конечно мне просто не повезло и я попал в самую, самую дремучую чащу. Но судя по всему QSqlRelationalTableModel более чем глючный класс. “Now I do not use QSqlRelationalTable model at all. Useless class. To many errors… and not so good design also.” Qt bugtracker, Дык вот, я полностью согласен. В попытках его освоить нашел 3 или  4 бага, потерял кучу дней. Научившись обходить часть из них и модицифировав базу данных под его “требования”, уперся в очередную проблему. Выжимка из моих проблем с QSqlRelationalTableModel  и ссылки на баги на форуме1.

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

Сегодня утром пишу код для работы с датами, выбрал формат для хранения в бд второй, для отображения на экране. В итоге не работает. Думал опять код работы с бд глючит. Оказалось нет, правду видимо мне сказали что у меня карма плохая поэтому я на баги нарываюсь – из 7 встроенных в Qt форматов перевода времени в строку и обратно, я выбрал Qt::SystemLocaleLongDate – единственный который не работает:) Добавил баг в багтрекер, можно поздравить с почином. Но на фоне QSqlRelationalTableModel, это уже мелочи – просто выбрал другой формат времени, ерунда:)

Ну и раз уж я недавно жаловался на то что взял wxCalendarCtrl и там было пару мелких проблем, то справедливости ради обязан заметить, что QCalendarWidgets – тоже не идеален, сегодня прикручивал. Есть проблемы как в отображении, так и в поведении, и я бы не сказал что совсем мелкие… Но сейчас я уже почему-то спокойнее к этому отношусь 🙂


Qt – те же яйца только в профиль?

May 21st, 2010 Begemot

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

Вернее сделал я это быстро, а потом долго пытался понять почему QDataWidgetMapper автоматически не сохраняет данные, вернее сохраняет, но только 1 раз для первого редактируемого поля. Искал где я мог накосячить, рыл интернет, мысль о баге в либе конечно возникала, но поверить в том что в Qt такая явная бага было трудно.

Похоже все таки действительно бага, вот описание проблемы и не одного ответа, вот баг репорт – обратите внимание на даты.

Или это мне так дико не везет или нет в мире совершенства 🙂

P.s. вот еще тикет по этому же багу, почему-то просто тупо закрыт…


Бег по минному полю к Qt

May 16th, 2010 Begemot

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

Обновился в транке то последней ревизии – бах. Взял компонент который раньше не юзал – бах, бах. , попробовал под мак компилять – бах, бах, бах. И это не образно, это реально то на что я попал за неделю. Каждая проблема это время, нервы, разочарование.

Сейчас повторяется недавняя история, когда я помучавшись с wxWidgets плюнул и написал программу на Objective-C\Cocoa. Потратив пару дней на написание прототипа гуи, вернее самых зачатков прототипа – для того что бы проверить архитеетуру\логику работы. GUI в принципе не самое простое, но и ничего сверх естественного.

Дальше начались проблемы, посидев полдня с напильником под виндой, перейдя с с wxNotebook на AUI версию – удалось добиться приемлемого поведения под виндой. Пошел под Mac OS – там все было достаточно печально, тот же wxAuiNoteebook ведет себя совсем не так как надо (и это я не использовал никаких продвинутых возможностей, типа открепления\перемещения вкладок, просто их показ).

Конечно, я уверен что не решаемых проблем особо нет – можно было опять же достать напильник (что в принципе нормально), изменить подход к построению гуи, вернутся на родной Noteebook, попробовать второй, третий вариант и так далее.

Но что-то я уже был злой и раздосадованный, человек (можно сказать апологет wxWidgets!) стал убеждать, что для моей задачи лучше все-таки использовать Qt, заказчик был изначально больше за Qt чем за wxWidgets…

В общем теперь я очень срочно учу Qt 🙂 Пока остановились на варианте – пишу прототип на нем и потом мы смотрим, сравниваем  и выбираем, но что-то мне подсказывает, что я знаю чем все закончится 🙂


wxWidgets vs QT

January 31st, 2009 Begemot

Ну вот прошло две недели после новости про qt lgpl, страсти вокруг открывающихся перспектив кажется немного поутихли. Я тоже вроде немого остыл. Первое мысль была что делать – говорят Qt лучше начинать что ли ее осваивать – с одной стороны заманичиво, с другой стороны придется все начинать с нуля, а осваиваю я крайне медленно:) Тем не менее желание было, что называется загорелся. Даже скачал саму библиотеку, кучу книжек к ней, позаносил в закладки сайты…

Больше всего меня растроило и убедило думать о смене библиотеке,  то что даже люди которых я считал чуть ли не апологетами wxWidgets в рунете – в один голос сказали что QT все-таки продвинутее и надо переходить на нее:(

Но несмотря на все хвалебные диферамбы в адресс qt у нее есть пару минусов, первое что мне очень не нравится это не-нативность контролов – я сам сейчас пытаюсь привыкнуть к KVirc  и кривость поведения обычных едит-боксов уже не раз заставляла меня вспоминать разработчиков, их родственников по женской линии и кривость рук. Окончательно меня добил пост на rsdn

Я после того, как пришлось несколько лет назад портировать продукты на Mac от QT плююсь. И не потому, что либа плохая, как раз наоборот — программировать приятно и удобно. Потому ее и выбрал ( ага, на безрыбье-то  ) Но… Пользователи ее терпеть не могут. Точнее то, как при ее использовании выглядит продукт. А выглядит он нестандартно и работает тоже нестандартно. Мелочей подобных описанным выше навалом  ! В итоге mac-пользователи мягко говоря разочаровываются. И высказывают это свое разочарование на форумах в духе “Ну не знаю… может где-то оно и нормально работает, но вот на mac это дерьмо дерьмом и пользоваться нормально невозможно”. Ну нафиг мне такое счастье, я лучше GUI отдельно напишу, значительно дешевле выходит в итоге.

Кстати, почему-то широко распространено мнение, что Opera на QT написана. Так вот, нифига подобного! Точнее уже нифига подобного, они QT они отказались еще в 2003, бо как столкнулись с точно такими же проблемами.

Я уже было решил потренироватся на кошках, в смысле не проекте который не включает стандартное гуи, а как раз наоборот требует универсального и одинакового custom draw look. Но тут вылез второй большой минус (имхо) насколько я понял маленькие приложения и qt понятия диаметрально противоположные.  Еще одна цитата  с rdsdn

А>Есть некое приложение для конечного клиента, которое использует динамическую линковку с библиотеками Qt.
А>Сами библиотеки не маленькие, а вместе с приложением, прямо скажем, довольно большенькие…

Собирал qt 4.4.3 с выключенными rtti, exceptions, accessibility(интересно, кто нибудь использует эту красоту?), qt3support.

Резльтат по размеру —
hello world статически слинкованный пример с одним виджетом, — 6.02 Мб, зависимость только от системных библиотек windows.
Он же запакованный — 2.8 метра.

Почему-то не собирались примеры с веб китом… Постоянно показывались ошибки линковки на классы, экспортируемые из QtWebKit, хотя сам libQtWebKit.a собрался.

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


wxWidgets vs QT статистика навевает на размышления

February 16th, 2008 Begemot

Просматриваю форум по с++ на RSDN. Замечаю что вопрос про QT намного больше чем по wxWidgets. Интересно… решил проверить поиском по форуму RSDN

По запросу ‘wxwidgets’ найдено документов: 693
По запросу ‘wxwindows’ найдено документов: 299

В сумме меньше тысячи. А вот QT

По запросу ‘qt’ найдено документов: 4349

В 4.5 раза больше. С чего бы это? И это при бесплатности wxWidgets и более чем платности QT. Ясно что кто-то опен соурс пишет, кто-то на работе на купленной работает, а кто-то и ворованной пользуется – но в 4.5 раза больше… не нравится мне это.