понедельник, 7 декабря 2009 г.

Настоящий программист

Понравилась цитата:
Настоящий программист не использует буфер обмена. (с)

От себя добавлю - Настоящий программист использует наследование.

четверг, 26 ноября 2009 г.

Недалекий gcc

Сегодня случилось компилировать кусок с рекурсивным удалением каталогов под Linux.
Здесь про рекурсивное удаление
Компилятор gcc преподнес сюрприз. Не хотел компилировать безобидный кусок кода:
int removeFolder(QDir & dir)
{
......
QString entryAbsPath = dir.absolutePath() + "/" + entry;
removeFolder(QDir(entryAbsPath));
......
}

То есть здесь идет рекурсивный вызов функции removeFolder(QDir &). В качестве параметра я передаю временный объект QDir, предполагая, что компилятор сможет получить ссылку на временный объект. Это не вызывает трудностей у MS Studio 2005, но повергает в шок gcc.
Пришлось за него самому создавать объект. В итоге код пришлось переписать в :
int removeFolder(QDir & dir)
{
......
QString entryAbsPath = dir.absolutePath() + "/" + entry;
QDir dr(entryAbsPath);
removeFolder(dr);
......
}

пятница, 30 октября 2009 г.

Рекурсивное удаление каталогов в Qt

Удаляем рекурсивно папки.

//Функция удаления папки
int removeFolder(QDir & dir)
{


int
res = 0;
//Получаем список каталогов
QStringList lstDirs = dir.entryList(QDir::Dirs |

QDir::AllDirs |
QDir::NoDotAndDotDot);
//Получаем список файлов
QStringList lstFiles = dir.entryList(QDir::Files);

//Удаляем файлы
foreach (QString entry, lstFiles)
{

QString entryAbsPath = dir.absolutePath() + "/" + entry;

QFile::remove(entryAbsPath);
}


//Для папок делаем рекурсивный вызов
foreach (QString entry, lstDirs)
{


QString entryAbsPath = dir.absolutePath() + "/" + entry;

removeFolder(QDir(entryAbsPath));
}


//Удаляем обрабатываемую папку
if (!QDir().rmdir(dir.absolutePath()))
{


res = 1;
}

return
res;
}

четверг, 29 октября 2009 г.

Расширение типов зависимостей в форме ввода

Некоторые люди спрашивают, почему у тебя в форме ввода зависимости между компонентами обусловлены по RTTI? Ведь это налагает ограничения на разновидности зависимостей. То есть, ты четко прописываешь связку, например, FSexEdit (выбор пола) и FComboList (список фамилий) и в зависимости от пола меняешь окончания фамилий. А если тебе надо будет добавить некую другую зависимость, когда в FComboList будут не фамилии а нечто другое, как тогда?

Отвечаю, добавление новой зависимости не составит труда. В утилите Rule нужно добавить третий параметр - тип зависимости.

Вот код утилиты Rule::applyRule

void Rule::applyRule(const AbstractFormComponent & master, AbstractFormComponent & slave)
{

   //преобразование мастера   const FSexEdit * masterSex = dynamic_cast<const FSexEdit *>(&master);

   //преобразование раба   FComboTextList * slaveCombo = dynamic_cast<FComboTextList *>(&slave);

   //зависимости от секса   if (masterSex)
   {
      if (slaveCombo)
      {

         apply(*masterSex, *slaveCombo);
      }
   }
}

Как видно из кода - я делаю динамическое преобразование с помощью dynamic_cast, а затем в зависимости от результата вызываю функцию apply, аргументами которой являются уже конкретные типы FSexEdit и FComboTextList.
Чтобы расширить набор зависимостей, мне нужно в функции apply добавить третий параметр - вид зависимости.
void Rule::apply(const FSexEdit & sex, FComboTextList & combo, int depType)


Тип зависимости будет узнавать функция applyRule из экземпляра master.

Так, что изменения минимальны, код легко расширяется. Все изменения не выходят за границы утилиты класса.

вторник, 27 октября 2009 г.

Реализация зависимостей в форме ввода

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

Это ведет к усложнению проекта. Проект должен быть прост и красив, но сделать просто очень трудно.

Дальше технические детали.

понедельник, 26 октября 2009 г.

Ваяем форму ввода

Продолжаю ваять Форму ввода текста.

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

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


class AbstractFormComponent
{
public:
void setName(const QString & name)
{
name_ = name;
}

QString name() const
{
return name_;
}
virtual void setValue(const QVariant &) = 0;
virtual QVariant value() const = 0;

protected:
virtual QWidget * widget() const = 0;
virtual void setCaps(Caps) = 0;

private:
QString name_;

};


Класс содержит пару функций для задания имени компонента, чтобы каждый компонент мог сказать как его зовут.
Дальше идут две основополагающие функции setValue и value. Они устанавливают и получают значение компонента.
Здесь пришлось использовать тип QVariant, хотя мне хотелось бы это сделать на чистом С. Тип QVariant удобен тем, что может хранить любой тип - int, QString, QDate и многие другие.
Каждый компонент сам понимает с каким типом он работает, преобразует QVariant в нужный тип и работает с ним.

Далее идет функция widget() - она возвращает виджет, который будет отражен на форме.

Такой подход, т.е. наследование всех компоненто от единой основы, позволяет отделить интерфейс компонента от реализации. Например, если захочу я переписать компонент QComboBox, то все что мне понадобится, чтобы пристыковать новый компонент - это соблюсти небольшой интерфейс абстрактного класса AbstractFormComponent.

А все компоненты я могу поместить в вектор

QVector<AbstractFormComponent *> components_;

и работать с ними как с одним типом.

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

пятница, 18 сентября 2009 г.

Работа в Перми на Qt

Предлагали седня работу в Перми. Что-то писать на Qt, под некий прибор. Можно удаленно, прибор обещали выслать на дом.
Я отказался, но может кому интересно.
Из нашей переписки
На самом деле прибор выслать никаких проблем нет. Ему нужно только 10-30В. И провод из компа с miniUSB. Прошивку в прибор, я могу через интернет загонять, а можете и Вы сами через USB (это для случая интенсивной работы совместной). У вас инет быстрый и скоростной?
Расскажу о нас. Мы фирма к-ая засталяет глаза и рты клиентов широко открываться от удивления (мы делаем невероятные вещи. Невероятные во всём). Для информации можете посмотреть на Galileosky.com. Оболденный дизайн. Обалденный функционал. Обалденная надежность. У него есть юсби, в к-ом реализовано виртуальный ком-порт. Налажен протокол и внедрен в прибор. Написана прога на билдере (первая версия конфигуратора). Работает отлично, но хочем переделать. Вот только у нас нет специалиста к-ый бы разработал шикарную прогу "конфигуратор", к-ая бы позволила широко открыть глаза и рты клиентов!


Ссылка на объяву

среда, 16 сентября 2009 г.

pro файлы против vcproj

Есть два метода создания нового проекта под Qt.
Один мой, другой неправильный. Тот что мой, на самом деле, общеупотребителен.
Новый проект начинается написания pro-файла. В нем описываются все исходники, зависимости, используемые библиотеки и т.п.
Полученный файл легко преобразуется в Makefile под nix системы или в vcproj для Visual Studio под виндой.

Теперь о неправильном методе. Непонятно с какого перепугу у нас на работе повсеместно используют непосредственно студию для создания нового проекта. Создают в ней новый проект и потом давай лазить по опциям проекта и выставлять всякие вещи.
Этот метод надо запретить под страхом смертной казни, потому что:
а) лазание по опциям проекта утомительно и гиморно
б) проект непереносим - на вопрос что делать если надо перенести под nix коллеги отвечают: а) написать вручную Makefile, б) написать конвертер из vcproj в pro-файл

На мой вопрос зачем такой гимор, когда надо всего лишь посмотреть на создание проекта с другого конца, пожимают плечами. Вот что значит зашоренность и привычка к студии. Qt Software(она же Trolltech, она же Nokia) создала замечательный инструмент qmake, который игнорируется некоторыми несознательными личностями.

воскресенье, 13 сентября 2009 г.

Форма ввода текста

Озадачился полностью отрефакторить форму ввода текста, писанную на Qt.
Форма ввода текста - это простая dll-ка, которая по xml-файлу создает полноценный виджет со всеми нужными полями ввода. У формы до кучи самописных компонентов, которые все так или иначе регулируются своими свойствами.

Итак, рефакторинг я начну с постановки технического задания, раз уж ранее не додумался до этого.