Mac Style

August 18th, 2010 Begemot

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


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


Поиск в SQLite без учета регистра, для русского языка

August 14th, 2010 Begemot

Не смотрю на всю свою юникодность, SQLite все-таки юникодна не до конца:( При поиске типа WHERE description LIKE “%STRING%” поиск идет без учета регистра для латинских букв, но к сожалению, он регистрозависимый для всех остальных символов. Корни этого уходят в виндовую функцию tolower(), которая правильно обрабатывает символы только текущей локали. И это весьма плохо, для целого ряда задач, например для поиска ранее скопированного текста в истории буфера обмена (извините, не удержался:))

Но к счастию способ есть. Оригинал и файлы для загрузки тут – SQLite and native UNICODE LIKE support in C/C++ . А я раскажу о том как это интегрировать и скрестить с wxDatabaselayer’om.

  1. Берем файлы sqlite3_unicode.h/c с архива по ссылке выше и добавляем в проект.
  2. Вызываем свойства sqlite3_unicode.c  и добавляем SQLITE_ENABLE_UNICODE; SQLITE_CORE в определения препроцессора c++/preprocessor/preprocessor definitions
  3. Если используете precompiled header в проекте, надо в свойствах обоих файлов отключить его использование.
  4. в с файле есть строчка #include “sqlite3.h” заменить ее на свой путь к sqlite3.h, если он у вас отличается
  5. Включить sqlite3.h в sqlite3_unicode.h, без этого у меня не компилилось.
  6. Дальше вызываете sqlite3_unicode_load();  \  sqlite3_unicode_free();  –  в начале/конце программы
  7. После открытия базы данных вызываем для нее sqlite3_unicode_init(db);

Проблема тут в том что sqlite3_unicode_init(db); хочет db типа sqlite3 *, а у нас есть только указатель на обьект датабайслаера. Тут придется править код самого wxDatabaselayer’a и заново компилить. Идем в databaselayer\include\SqliteDatabaseLayer.h, пишем:

// Added by Begemot – for using with  sqlite3_unicode
void * GetSQLiteDatabase()  { return m_pDatabase; } 

компиляем, и в нашей программе вместо строчки sqlite3_unicode_init(db); используем вот такую вот страшную конструкцию

sqlite3_unicode_init(static_cast<sqlite3*>(static_cast<SqliteDatabaseLayer*>(db)->GetSQLiteDatabase()));

Все. Теперь Like % прекрасно ищет по русским или любым другим символам без учета регистра.


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


Тащим 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)

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

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


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


wxWidgets определение размера экрана

June 22nd, 2010 Begemot

В wxWidgets есть wxSystemSettings::GetMetric() который, кроме прочего, позволяет узнать разрешение экрана, но к сожалению не правильно 🙁

Проблемы появляются на мультимониторных конфигурациях. Вызов wxSystemSettings::GetMetric(wxSYS_SCREEN_X); дает нам ширину только первого монитора под Windows (сам проверял) и суммарную ширину обоих мониторов под Линуксом (сведенья из инета). Подозреваю что это баг, но разбиратся, формулировать и спорить некогда, поэтому просто написал воркараунд для себя

#ifdef __WIN32__  
    // wxSystemSettings::GetMetric does not support multy-monitor configuration at Windows, and return parameters only for first monitor, but it seems wots fine under Linux
    const int maxWidth = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
    const int maxHeight = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
#else
    const int maxWidth = wxSystemSettings::GetMetric(wxSYS_SCREEN_X);
    const int maxHeight = wxSystemSettings::GetMetric(wxSYS_SCREEN_Y);
#endif

Updated:
Эхх стало стыдно за плохой стиль:(

// wxSystemSettings::GetMetric does not support multy-monitor configuration at Windows and return parameters only for first monitor, but it seems works well under Linux
wxSize BegUtils::GetVirtualDisplayResolution()
{
#ifdef __WIN32__  
    return wxSize(::GetSystemMetrics(SM_CXVIRTUALSCREEN), ::GetSystemMetrics(SM_CYVIRTUALSCREEN));
#else
    return wxSize(wxSystemSettings::GetMetricwxSYS_SCREEN_X), wxSystemSettings::GetMetricwxSYS_SCREEN_Y));
#endif
}


...

    const wxSize resolution = BegUtils::GetVirtualDisplayResolution();

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


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 – тоже не идеален, сегодня прикручивал. Есть проблемы как в отображении, так и в поведении, и я бы не сказал что совсем мелкие… Но сейчас я уже почему-то спокойнее к этому отношусь 🙂


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


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

May 21st, 2010 Begemot

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

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

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

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

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


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


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

May 16th, 2010 Begemot

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

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

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

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

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

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

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


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


wxPropertyGrid – довольно удобно

May 11th, 2010 Begemot

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

Теперь я нашел выход, делаем в опцию одну страницу Advanced, суем туда wxPropertyGrid, теперь отпадает проблема усложнения GUI кучей мелких опций. К тому же добавление новых настроек превращается в простой и быстрый процесс.

image


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


Как я изменил wxWidgets

April 13th, 2010 Begemot

Предложили мне тут портировать одну маленькую утилиту для автоматического выключения звука на Mac OS, я сказал что если возьмусь то только на c++\wxWidgets, зачем мне осваивать новый язык\библиотеку…

Лихо написал программу под винду и полез под макос, в надежде на быстрое портирование, обламался:)

Сначала долго пытался вообще заставить вх собираться и давать мне собрать примеры на маке, потом изучал cmake, потом перешел с carbon версии wxWidgets на более новую cocoa сборку…

В принципе, тут дело в том что у программы достаточно специфичные требования:

  1. Программа маленькая.
  2. Иконка в трее.
  3. Глобальная горячая клавиша.

Последнее вообще не поддерживается в вхВиджетс под маком, второе недавно появилось – но работает через 1 место, ну и размер…

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

Objective-C имеет достаточно специфический синтаксис, но в принципе не сложен. Да и в целом писать под мак мне понравилось – такое впечатление что там это как-то гораздо больше продуманнее все.

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

Если кому интересно, посмотреть что получилось, можно тут.


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


Еще один перевод туториала по wxWidgets

March 31st, 2010 Begemot

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

Да и в целом сообщество по wxWidgets в livejournal я смотрю ожило, что тоже не может не радовать.


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




Page 2 of 1512345678Last »