Russian Qt Forum
Октябрь 01, 2024, 02:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Как правильно реализовать?  (Прочитано 4625 раз)
XpycT
Гость
« : Август 30, 2009, 12:37 »

Всем привет.
Есть у меня приложение, которое является клиентом для трекера. На данный момент работает только с TBDev Yuna Edition. Хотелось бы добавить поддержку других типов трекеров (XBT,Btit,TorrentPier и т.п.), и думаю оформить это в виде динамических библиотек.
Вопрос вот в чем:
Предположим при запуске(и в настройках) приложения я сделаю,например, QComboBox, и зависимо от его выбора будет использоваться нужный набор запросов к серверу и их  обработка. Вот не совсем понимаю как это реализовывать. Это мне надо создавать классы с одинаковой структурой или как? Почему-то в голову кроме как switch'a ничего не приходит:
Код
C++ (Qt)
int type= comboBox->currentIndex(); // получаю тип трекера
switch(type){
case 0:
// запрос авторизации для одного типа трекера
break;
....
case n:
// запрос авторизации для другого типа трекера
break;
}
Кажется мне что я думаю не в том направлении, может кто подскажет как лучше сделать  В замешательстве
Записан
BlackTass
Гость
« Ответ #1 : Август 30, 2009, 12:59 »

Ну наиболее логичным вариантом будет создать pure virtual базовый класс и сделать кучку его наследников (по одному на каждый трекер). И соответственно при смене селекшена в вашем комбобоксе вы будете подменять объект работы с трекером (предварительно убив старый и инциализировав новый).
К вопросу о том как создавать новый инстанс нужного нам типа. Можно через тот же свитч; можно завести в базовом классе енум, который будет отображать все множество наследников (хотя мне такой вариант не очень нравится, он нарушает основы ООП, так как предок будет знать о потомках; лучше сделать еще один класс (вне иерархии классов для трекеров), который будет хранить этот енум и отдавать нужный инстанс наследников нашего базового класса); можно работать по какому-либо более тяжелому ключу, чем просто инт (например по некоему строковому ключу). В последнем случае можно сделать копию иерархии классов для трекеров, которая будет нести чисто утилитный смысл - отдавать нужный инстанс и уже инстансы утилитных классов хранить в ассоциативном массиве или еще в какой-нить структуре.

Я это к чему  Улыбающийся Вариантов решения проблемы много.
Записан
SABROG
Гость
« Ответ #2 : Август 31, 2009, 14:50 »

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

По идее можно вынести в базовый класс общий функционал для всех трекеров. Методы, которые должны работать несколько иначе в зависимости от версии трекера сделать виртуальными. Затем унаследоваться от этого класса и реализовать несколько вариантов с которыми ты умеешь работать. В combobox (или в какую-нибудь структуру settings) можно поместить ссылку/указатель на объект подобного класса и вызывать его методы. Можно конечно воспользоваться еще шаблонами, но это дублирование кода.

Кстати, а нужен ли этот комбобокс вообще? Программа может автоматически определять версию трекера?
Записан
XpycT
Гость
« Ответ #3 : Август 31, 2009, 18:47 »

Цитировать
Кстати, а нужен ли этот комбобокс вообще? Программа может автоматически определять версию трекера?
Дело в том что начальная версия проги работала через некий PHP-API, но в данный момент я пытаюсь полностью от него оказаться. Единственный вариант определения типа трекера я вижу только получения какой-то страницы, ее парсинг и выдерку некой информации, которая есть только в данном типе трекера. Ясно что с api это намного проще - но тогда использование клиента становится реально только при условии установки данного api владельцем трекера Улыбающийся

В принципе попробую базовым классом, Но сегодня разбирал структуру TorrentPier и понял что наследованием от базового класса не обойтись, ну или в крайнем случае придется его сильно "раздуть" Грустный .
Записан
XpycT
Гость
« Ответ #4 : Сентябрь 01, 2009, 13:22 »

Возникла проблемка, почему-то QMap передается только со второго раза. Получается у меня виртуальный класс :
Код
C++ (Qt)
class TrackerRequest: public QObject
{    
public:
   TrackerRequest(){}
   virtual void checkLogin() = 0;
   virtual void getCategory() = 0;
   virtual QMap<int,QString> returnCategory(){return catmap;}
protected:
   QMap<int,QString> catmap;
};
и его наследник *.h
Код
C++ (Qt)
class TrackerTBDevYuna : public TrackerRequest
{
   Q_OBJECT
public:
   QMap<int,QString> returnCategory(){return catmap;}
private:
   QMap<int,QString> catmap;
};
в *.cpp получаю категории и заполняю catmap
Код
C++ (Qt)
QRegExp rx2("<option value=\"([^0]*)\">(.*)</option>");
   rx2.setMinimal(true);
   int pos = 0;
    while ((pos = rx2.indexIn(text, pos)) != -1) {
        catmap.insert(rx2.cap(1).toInt(), rx2.cap(2));
        pos += rx2.matchedLength();
    }
а в основном приложении при клике на кнопку беру карту и заполняю с нее комбобокс
Код
C++ (Qt)
QMap<int,QString> map;
   map = tracker->returnCategory();
   qDebug() << map.count();
 
    QMapIterator<int,QString> i(map);
    while (i.hasNext()) {
        i.next();
        cb->addItem(i.value());
    }

Но вот почему-то он заполняется только после второго клика, а на первом карта остается пустой Грустный
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #5 : Сентябрь 01, 2009, 14:29 »

у тебя virtual QMap<int,QString> returnCategory() и QMap<int,QString> catmap; дублируются в базовом классе и наследнике. Оставь только в базовом классе.
Записан
XpycT
Гость
« Ответ #6 : Сентябрь 01, 2009, 15:32 »

у тебя virtual QMap<int,QString> returnCategory() и QMap<int,QString> catmap; дублируются в базовом классе и наследнике. Оставь только в базовом классе.
Спасибо, помогло Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.159 секунд. Запросов: 23.