Russian Qt Forum

Qt => Вопросы новичков => Тема начата: surendil от Август 19, 2011, 00:04



Название: QList и indexOf
Отправлено: surendil от Август 19, 2011, 00:04
Здравствуйте :) Ломаю голову над проблемой уже шестой час, но никак не могу понять, почему не работает. Помогите пожалуйста...

Я хочу сделать QList< USBID* > и искать их по indexOf(). Как было написано в документации на QList, я реализовал в USBID оператор сравнения, получилось так:
Код
C++ (Qt)
bool USBID::operator ==(USBID &cmpId) const
В ходе отладки выяснилось, что до выполнения моего operator == дело не доходит.


Название: Re: QList и indexOf
Отправлено: kambala от Август 19, 2011, 00:25
эта функция сравнения подойдет для QList<USBID>, а для QList<USBID *> нужно реализовать функцию bool USBID::operator ==(USBID *cmpId) const


Название: Re: QList и indexOf
Отправлено: surendil от Август 19, 2011, 00:33
Всё равно не работает :'( А я правильно думаю?
Код
C++ (Qt)
USBID meow(vID);
int foundIndex = m_ids->indexOf(&meow); // QList< USBID* > *m_ids;


Название: Re: QList и indexOf
Отправлено: LisandreL от Август 19, 2011, 01:00
Вам был бы нужен был бы оператор
bool operator == ( const MyString * cmpId, const MyString * cmpId2 );
Но оператор с 2 ссылками перегрузить вам не удастся.


Название: Re: QList и indexOf
Отправлено: kambala от Август 19, 2011, 01:08
Всё равно не работает :'( А я правильно думаю?
Код
C++ (Qt)
USBID meow(vID);
int foundIndex = m_ids->indexOf(&meow); // QList< USBID* > *m_ids;
если meow - это какая-то локальная переменная, то она получит новый адрес, которого точно нету в m_ids (а если вдруг такой адрес там и найдется, то он все равно будет указывать на другой объект)


Название: Re: QList и indexOf
Отправлено: LisandreL от Август 19, 2011, 01:10
kambala, я думаю он хотел перегрузить оператор ==, что бы сравнивались не указатели, а то, на что они указывают.


Название: Re: QList и indexOf
Отправлено: LisandreL от Август 19, 2011, 01:28
Впринципе вместо указателя можно использовать класс (самописный или существующий).

Нечто вроде:
Код
C++ (Qt)
bool operator ==( const QPointer< USBID > &cmpId, const QPointer< USBID > &cmpId2 )
{
   return *cmpId == *cmpId2;
}
 
USBID meow(vID);
int foundIndex = m_ids->indexOf(&meow); // QList< QPointer< USBID > > *m_ids;

Примечание 1: QPointer требует чтобы USBID наследовалось от QObject.
Примечание 2: Я бы на вашем месте отказался от QList::indexOf.


Название: Re: QList и indexOf
Отправлено: kambala от Август 19, 2011, 01:30
да, точно :)

тогда если объекты типа USBID и так где-то хранятся, почему бы не хранить их прямо в QList<USBID>?


Название: Re: QList и indexOf
Отправлено: surendil от Август 19, 2011, 01:44
И правда, классы изначально кривые, отсюда и сложности.
Спасибо вам за советы, утром буду пробовать ^_^


Название: Re: QList и indexOf
Отправлено: Igors от Август 19, 2011, 03:00
indexOf - всего лишь линейный перебор, да и нет смысла его переопределять - напр он может потребоваться для нахождения указателя. Иногда продуктивен подход типа "да чихал я на Ваши функторы!", напр

Код
C++ (Qt)
template <class T1, class T2>
int IndexOfValue( const T1 & src, const T2 & match )
{
for (int i = 0; i < src.size(); ++i)
 if (*src[i] == match)
  return i;
return -1;
}
 


Название: Re: QList и indexOf
Отправлено: surendil от Август 19, 2011, 10:36
Я отказался от затеи с QList :D получилось так:

Код
C++ (Qt)
class USBIDs
{
// ...
public:
 bool findDevice(const QString &vID, const QString &pID);
 QString vendorName() const
 QString productName() const;
 
private:
 QHash< QString, USBInfo > *m_ids;
 QString m_selectedKey;
};
Код
C++ (Qt)
bool USBIDs::findDevice(const QString &vID, const QString &pID)
{
 m_selectedKey = vID + pID;
 return m_ids->contains(m_selectedKey);
}
 
QString USBIDs::vendorName() const  { return m_ids->value(m_selectedKey).vendorName; }
QString USBIDs::productName() const { return m_ids->value(m_selectedKey).productName; }


Название: Re: QList и indexOf
Отправлено: Igors от Август 19, 2011, 20:30
Я отказался от затеи с QList :D получилось так:
m_selectedKey. xорошего впечатления не производит :)  Потом если Вам понадобится выводить поля USBInfo в определенном порядке, то нужен будет еще контейнер. А вот завернуть все поиски в USBIDs - идейка неплохая, может действовать примерно так

Код
C++ (Qt)
struct USBIDs : public QList <USBInfo> {
typedef QList <const USBInfo *> TUSBListPtr;
TUSBListPtr Lookup( const QString * vendorName, const QString * productName, int options ) const;
 
TUSBListPtr LookupByVendor( const QString & vendorName, int options = look_FullMatch  ) const;
{
 return Lookup(&vendorName, 0, options);
}
 
TUSBListPtr LookupByProduct( const QString & productName, int options = look_FullMatch  ) const;
{
 return Lookup(0, &productName, options);
}
 
enum {
 look_FullMatch = 0,
 look_StartsWith = 1,
 look_EndsWith = 2,
};
};
 


Название: Re: QList и indexOf
Отправлено: surendil от Август 20, 2011, 10:31
Чёрт, я ничего не понял :D Igors, можете в двух словах пояснить ваш пример? Пожалуйста ^^
Upd: кажется, чуть-чуть понял. А почему m_selectedKey было плохо?


Название: Re: QList и indexOf
Отправлено: Igors от Август 20, 2011, 13:33
Чёрт, я ничего не понял :D Igors, можете в двух словах пояснить ваш пример? Пожалуйста ^^
Upd: кажется, чуть-чуть понял. А почему m_selectedKey было плохо?
Вообще-то наследоваться от контейнера часто нехорошо, но здесь, мне кажется, нормально.  Насчет m_selectedKey - ну а как Вы его будете пользовать?
Код
C++ (Qt)
if (uids.findDevice(vendor, product)) {
// а здесь что?
return uids.vendorName();  // нет смысла, это тот самый vendor  
}
 
Напр потребуется подсчитать (или показать) все продукты такого-то vendora - и что, опять класс делать? Разумно выглядит зарядить все выборки в одном месте, пусть пока 1, по мере необходимости будете расширяться внутри класса
Код
C++ (Qt)
TUSBListPtr lst = uids.LookupByVendor(vendor);
 
// теперь по каждому USB этого vendora
for (int  i = 0; i < lst.size(); ++i)
  // печатаем, выводим и.т.п.
}
 


Название: Re: QList и indexOf
Отправлено: surendil от Август 21, 2011, 00:38
Я подумал и остановился на ассоциативных массивах. Получилось плоско, но вроде бы попроще :)
Код
C++ (Qt)
class USBID_Vendor
{
// ...
private:
 QString _name
 QHash< QString, QString > _products; // ID, Name
};
Код
C++ (Qt)
class USBIDs
{
// ...
private:
 QHash< QString, USBID_Vendor > _ids
};


Название: Re: QList и indexOf
Отправлено: Igors от Август 21, 2011, 11:29
Я подумал и остановился на ассоциативных массивах. Получилось плоско, но вроде бы попроще :)
Это решает одну задачу (получить ID по имени). А если надо имя по ID? А если есть 2 или более ID с тем же именем или наоборот? Надо считать хотя бы на 1 ход вперед  :)


Название: Re: QList и indexOf
Отправлено: surendil от Август 21, 2011, 13:28
Я подумал и остановился на ассоциативных массивах. Получилось плоско, но вроде бы попроще :)
Это решает одну задачу (получить ID по имени). А если надо имя по ID? А если есть 2 или более ID с тем же именем или наоборот? Надо считать хотя бы на 1 ход вперед  :)
ID по имени? Мне наоборот нужно :) для очередного USB устройства я получаю VendorID и ProductID, для которых нужно получить соответственно, название производителя и устройства. ID производителей не повторяются, устройств, полагаю, тоже.


Название: Re: QList и indexOf
Отправлено: Igors от Август 21, 2011, 18:10
ID по имени? Мне наоборот нужно :) для очередного USB устройства я получаю VendorID и ProductID, для которых нужно получить соответственно, название производителя и устройства. ID производителей не повторяются, устройств, полагаю, тоже.
Нужно также полагать что

- 2 "просто одинаковых" устройств быть не может
- показать/напечатать все устройства такого-то вендора не требуется
- не требуется  даже печатать устройства в том порядке что они обнаружены

Иначе Ваша реализация не проходит (наверное требования слишком завышены  :))


Название: Re: QList и indexOf
Отправлено: surendil от Август 21, 2011, 23:28
Нужно также полагать что

- 2 "просто одинаковых" устройств быть не может
- показать/напечатать все устройства такого-то вендора не требуется
- не требуется  даже печатать устройства в том порядке что они обнаружены

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

Зачем всё это, если от реализации требуется всего лишь адекватно отвечать на чётко поставленный (один) вопрос?


Название: Re: QList и indexOf
Отправлено: Igors от Август 22, 2011, 09:48
Зачем всё это, если от реализации требуется всего лишь адекватно отвечать на чётко поставленный (один) вопрос?
Вернемся к вопросу-первоисточнику

Я хочу сделать QList< USBID* > и искать их по indexOf().
Отсюда я делаю вывод что у Вас имеется набор (массив, контейнер) USBID имеющих vendorID. productID (ключ). Наверное у Вас есть набор устройств (откуда-то получен) и задача найти/проверить есть ли устройство с такими-то ID в Вашем списке. Если это не так - поясните, потому что не видно что еще здесь может иметь смысл.


Название: Re: QList и indexOf
Отправлено: surendil от Август 23, 2011, 09:22
Да, всё верно. Я получаю из реестра имена ключей, из них регулярным выражением добываю VID и PID. Есть файл USB.IDS (http://www.linux-usb.org/usb.ids). Задача сводится к тому, чтобы для очередного устройства с VID и PID получить название компании-производителя и название устройства.


Название: Re: QList и indexOf
Отправлено: Igors от Август 23, 2011, 10:20
Да, всё верно. Я получаю из реестра имена ключей, из них регулярным выражением добываю VID и PID. Есть файл USB.IDS (http://www.linux-usb.org/usb.ids). Задача сводится к тому, чтобы для очередного устройства с VID и PID получить название компании-производителя и название устройства.
Ага, а я-то думал у Вас расширяемый список устройств. Ну тогда не видно зачем городить какие-то свои классы если это решается на встроенных

Код
C++ (Qt)
typedef int TID;
typedef QHash <TID, QString> TProductHash;
typedef QPair <QString, TProductHash> TVendor;
typedef QHash <TID, TVendor> TVendorHash;
 
TVendorHash vendorHash;
 
// заполняем vendorHash из текстовика
 
bool Lookup( TID vendorID, QString & vendorName, TID productID, QString & productName )
{
TVendorHash::const_iterator itV = vendorHash.find(vendorID);
if (itV == vendorHash.end()) return false;
const TVendor & vendor = *itV;
vendorName = vendor.first;
TProductHash::const_iterator itP = vendor.second.find(productID);
if (itP == vendor.second.end()) return false;
productName = *itP;
return true;
}
 


Название: Re: QList и indexOf
Отправлено: surendil от Август 23, 2011, 15:50
О, а я про QPair не знал :)
Спасибо вам за помощь :D