Places Backend
Обзор
Интерфейс QPlaceManager, предоставляемый клиентам для доступа к информации о местах, напрямую зависит от реализации QPlaceManagerEngine. Движок предоставляет реализации функций бэкэнда, которые вызываются менеджером.
Реализатор бэкэнда мест должен наследовать от QPlaceManagerEngine и предоставить реализации виртуальных функций, относящихся к их бэкэнду. Большинство этих функций асинхронные, поэтому реализаторы также должны наследовать соответствующие классы ответов. Объекты ответов отвечают за управление асинхронным запросом; они используются для уведомления о завершении запроса и содержат результаты этого запроса. QPlaceManagerEngine предоставляет реализацию по умолчанию для всех виртуальных функций. Реализации по умолчанию для асинхронных функций возвращают ответ, который будет испускать сигналы error() и finished() на следующей итерации цикла событий.
Реализация/наследование объектов ответов
Объект ответа был бы унаследован следующим образом:
class SearchReply : public QPlaceSearchReply
{
public:
explicit SearchReply(ManagerEngine *engine)
: QPlaceSearchReply(engine), m_engine(engine){}
~SearchReply();
void setResults(const QList<QPlaceSearchResult> &results);
void setRequest(const QPlaceSearchRequest &request);
...
void triggerDone(QPlaceReply::Error error = QPlaceReply::NoError,
const QString &errorString = QString());
ManagerEngine *m_engine;
}; Реализация QPlaceManagerEngine должна гарантировать, что любые сигналы, испускаемые объектами ответов, откладываются до тех пор, пока функции запроса не вернутся, и код приложения сможет подключить эти сигналы к слотам. Типичный подход заключается в использовании QMetaObject::invokeMethod() с Qt::QueuedConnection для испускания сигналов.
void SearchSuggestionReply::triggerDone(QPlaceReply::Error error,
const QString &errorString)
{
if (error != QPlaceReply::NoError) {
this->setError(error,errorString);
QMetaObject::invokeMethod(m_engine, "error", Qt::QueuedConnection,
Q_ARG(QPlaceReply *,this),
Q_ARG(QPlaceReply::Error, error),
Q_ARG(QString, errorString));
QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
Q_ARG(QPlaceReply::Error, error),
Q_ARG(QString, errorString));
}
this->setFinished(true);
QMetaObject::invokeMethod(m_engine, "finished", Qt::QueuedConnection,
Q_ARG(QPlaceReply *,this));
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
} Обратите внимание, что сигналы finished всегда должны испускаться при завершении ответа, даже если была обнаружена ошибка. То есть, если есть ошибка, должны испускаться сигналы error и finished, в то время как если ошибки нет, испускаются только сигналы finished.
Защищенные функции QPlaceSearchReply::setResults() и QPlaceSearchReply::setRequest() сделаны общедоступными, чтобы плагин мог назначать результаты и запросы. Поскольку эти функции не экспортируются публично, вопрос о доступе не так актуален. Альтернативой было бы объявление дружественного класса в SearchReply.
Обычно экземпляр движка делается parent ответа. Если разработчик не удаляет ответы при завершении, движок может очистить их при уничтожении. Как правило, у ответа также есть ссылка на указатель обратно на движок, который может использоваться для испускания сигналов QPlaceManagerEngine::finished() и QPlaceManagerEngine::error(). Это всего лишь один из многих способов реализации ответа.
URL-адреса иконок
URL-адреса иконок предоставляются через функцию QPlaceManagerEngine::constructIconUrl(). Ожидаемое поведение состоит в том, что движок будет использовать QPlaceIcon::parameters() для построения соответствующего URL-адреса. Когда объект QPlace возвращается менеджером либо из поиска, либо из запроса для получения подробностей о месте, ожидается, что движок правильно заполнит параметры при необходимости.
Бэкенд свободен выбирать ключи и значения параметров, однако если у бэкэнда есть только один URL на иконку, рекомендуется использовать QPlaceIcon::SingleUrl в качестве ключа.
Категории
Категории движка менеджера — относительно статические сущности; для движков, обращающихся к удаленным хранилищам данных о местах, может быть целесообразно кэшировать структуру категорий, а не запрашивать сервер каждый раз, когда вызывается QPlaceManagerEngine::initializeCategories(). В зависимости от того, насколько динамичны категории, может быть предпочтительнее постоянно загружать самый свежий набор категорий.
Сохранение мест в менеджере
Место обычно не может быть сохранено напрямую между менеджерами, так как оно содержит данные, специфичные для менеджера, такие как значки и категории. Для обеспечения возможности сохранения в собственном менеджере реализаторы движков должны реализовать функцию QPlaceManagerEngine::compatiblePlace(). Эта функция возвращает копию входного места с усечёнными или изменёнными свойствами, так что копия может быть сохранена в менеджере.
Создание совместимого места может включать игнорирование определённых свойств из исходного места, например, если контактные данные не поддерживаются, они опускаются из совместимого места. В других случаях это может включать изменение определённых свойств, например, изменение параметров значка для облегчения копирования или загрузки значка исходного места в расположение, к которому бэкенд имеет доступ.
Перекрестное использование мест между менеджерами
Иногда возникает ситуация, когда необходимо сопоставить и связать места между менеджерами. Такая ситуация может возникнуть, когда один менеджер предоставляет только чтение для мест (исходный менеджер), а другой менеджер чтения/записи (менеджер назначения) используется для сохранения выбранных избранных элементов из первого. Во время поиска в исходном менеджере мы можем узнать, какие из них были «избраны» в менеджер назначения, и, возможно, отобразить настроенное имя избранного, а не оригинальное.
Альтернативное перекрестное использование идентификаторов
Для выполнения перекрестного использования необходимо установить связь между исходным местом и избранным местом, и это обычно обрабатывается через атрибут альтернативного идентификатора. Избранное место содержит атрибут альтернативного идентификатора, который содержит идентификатор исходного места.
origin R/O manager(here) destination R/W manager (places_jsondb)
Save
Place id: ae246 ---> Place id: 0001
Attribute type: x_provider Attribute type: x_id_here
Attribute value: here Attribute text value: ae246 Существует 3 предварительных условия для реализации перекрестного использования по альтернативному идентификатору. Во-первых, исходный менеджер должен предоставить атрибут x_provider со значением, являющимся именем QGeoServiceProvider менеджера. Метка атрибута должна оставаться пустой, указывая, что атрибут не должен отображаться пользователям.
Примечание: Ожидается, что все менеджеры установят атрибут x_provider.
Во-вторых, QPlaceManager::compatiblePlace() целевого менеджера использует атрибут x_provider начального места и устанавливает атрибут альтернативного идентификатора места для сохранения. Ключом атрибута альтернативного идентификатора является x_id_<provider name>, а текстовое значение — идентификатор начального места. Атрибут x_provider не должен передаваться совместимому месту. При сохранении x_provider сохранённого места считается менеджером назначения.
В-третьих, QPlaceManager::matchingPlaces() целевого менеджера принимает QPlaceMatchRequest::AlternativeId в качестве параметра ключа и ключ атрибута альтернативного идентификатора в качестве значения, в этом случае x_id_<provider name> должно быть ожидаемым значением. Это указывает, что идентификаторы мест в QPlaceMatchRequest должны сопоставляться с атрибутами альтернативного идентификатора x_id_<provider name>.
Обратите внимание, что если целевой менеджер должен поддерживать сохранение и перекрестное использование данных из любого произвольного менеджера, он внутренне должен поддерживать сохранение произвольных пар ключ-значение, поскольку мы не можем заранее знать имена поставщиков, а также не можем знать, какой структурой будут являться идентификаторы.
Другие методы связи
Если исходный менеджер не предоставляет идентификатор места, может потребоваться предоставить другие средства перекрестного использования/сопоставления. Одним из подходов может быть использование координат места, если координаты места в исходном менеджере идентичны или близки к месту в целевом менеджере, высока вероятность, что они являются одним и тем же местом. В этом случае менеджер может реализовать QPlaceManager::matchingPlaces() для приёма QPlaceMatchRequest с параметром ключа 'proximity' и значением параметра расстояния между двумя местами, необходимым для обнаружения совпадения. Например, если исходное и целевое место находятся на расстоянии менее 50 м друг от друга, их можно считать одним и тем же местом.
Однако, как правило, рекомендуется реализовать перекрестное использование через альтернативные идентификаторы, как указано выше.
Атрибуты расширения для чтения пользователем и нечитаемые пользователем
Если атрибут не предназначен для чтения конечными пользователями, поле метки должно оставаться пустым в качестве индикатора этого факта.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/location-places-backend.html