Показаны сообщения с ярлыком Qt. Показать все сообщения
Показаны сообщения с ярлыком Qt. Показать все сообщения

Qt 5.4: Отладка запуска приложения из командной строки

При развертывании приложения написанного с помощью Qt и, в частности, QML иногда полезно посмотреть, какие Qt и QML модули оно пытается найти. Особенно, если оно их найти не может. Например, в случае следующих ошибок:
This application failed to start because it could not find or load the Qt platform plugin "xcb" или
module "QtQuick.Window" is not installed Для этого можно выставить две переменные окружения:
QT_DEBUG_PLUGINS=1 - добавит вывод в консоль информацию о том, какие Qt плагины и где приложение пытается найти, и
QML_IMPORT_TRACE=1 - добавит вывод в консоль аналогичную информацию о модулях QML.
Ну и упомянутые выше ошибки можно вылечить, выставив следующие переменные окружения:
QT_QPA_PLATFORM_PLUGIN_PATH=/path_to_qt/Qt/5.4/gcc_64/plugins - для того, чтоб приложение смогло найти плагин xcb, и
 QML2_IMPORT_PATH=/path_to_qt/Qt/5.4/gcc_64/qml/ - для того, чтобы приложение смогло найти установленные модули QML

Qt 5.3 QML: Владение объектами С++

По умолчанию объекты, созданные в коде С++ и переданные в QML через Q_INVOKABLE методы или слоты передаются во владение Javascript. То есть если в QML передается указатель на объект, созданный в коде С++ динамически посредством вызова оператора new(), сборщик мусора Javascript удалит его по своему усмотрению: если на него не будет ссылок в Javascript, не будет родительского объекта (QObject::parent() будет пуст), или будет вызван деструктор соответствущего QQmlEngine. Это поведение можно изменить с помощью вызова статического метода:
void QQmlEngine::​setObjectOwnership(QObject * object, ObjectOwnership ownership)
Таким образом, если выставить только что созданному объекту значение QQmlEngine::CppOwnership, владение останется на стороне кода С++, и сборщик мусора его не тронет.

Qt 5.3 QML: как принудительно выполнить перерисовку элемента

Судя по всему, стандартные средства QML не позволяют просто взять и запросить перерисовку заданного объекта. Понятно, что объекты автоматчески перерисовываются при измении их свойств, списки автоматически перерисовываются при изменении привязанных к ним моделей. Но если есть какой-нибудь кастомный элемент интерфейса на основе, например, Rectangle, отрисовка которого зависит от какой-нибудь кастомной модели, проброшенной в QML из С++ кода, все это не поможет. Модель меняется, а вот метода, который бы заставил интерфейс перерисоваться заново с учетом этих изменений, я не нашел.
Единственное решение, которое я нашел, это удалить элемент и пересоздать его заново после изменения модели (как это делать, описано здесь). Правда, статически созданные элементы не рекомендуется удалять динамически, поэтому элементы, которые нужно будет пересоздавать, нужно сразу создавать динамически.

Qt 5.3 QML: создание линий без использования Canvas

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

Qt 5.3 QML: создание контейнера элементов больше размера окна

У меня возникла необходимость сделать в приложении, написанном на Qt 5.3 и использующим QML, контейнер элементов интерфейса, который был бы больше окна приложения, то есть какая-то его часть бы была видна пользователю, а все остальное - скрыто в данный момент. Это очень похоже на поведение любого графического редактора при увеличении открытого изображения - становится видна только часть изображения. Соответственно, необходимо также, чтоб была возможность "передвигать" мышкой видимую часть контейнера - при этом в окне должны отображаться скрытые ранее элементы.
В QML для этого есть специальный элемент-контейнер Flickable. Однако в чистом виде его использовать не удалось - поведение не совпадает с ожидаемым. Ниже представлен QML код, который реализует описанное поведение.

Qt 5.3: предоставление доступа к С++ объектам из QML

Связка Qt 5.3 + QML предоставляет отличную возможность разделить в приложении логику модели данных и логику представления. Но чтобы обеспечить свзять между моделью данных и представлением, необходимо предоставить представлению доступ к данным. Я это делаю через отдельную прослойку - Presenter (из Model-Vew-Presenter). Для этого я завожу отдельный класс, объекты которого, с одной стороны, имеют ссылку на объекты модели, а с другой, к ним может быть осуществлен доступ из QML - представления. Итак, необходимо предоставить из QML доступ к объектам в С++ коде.