Файл qml что это

QML и C++. Простой пример связки

Задача. Нужно написать программу QML в связке с С++, где
1. На форме располагается кнопка, строка ввода, и поле вывода.
2. Требуется считать из строки ввода число, прибавляется 1, и ответ выводится в поле вывода.
3. Интерфейс написан на QML.
4. Функционал на С++, то есть нам нужно обеспечить взаимосвязь между QML и C++: кнопка QML вызывает С++ функцию, а функция меняет свойства QML объектов.

Создание базового приложение QML

Создание QML приложения

2. В следующем окне выбираем название нашего проекта (без пробелов и русских букв). Например, в нашем случае это «Example«.

3. В следующем окне у Вас должна стоять галочка у «Desktop«. Если ее у Вас ее нет, то Вы неверно установили Qt Creator (или Вы намерено не хотите создавать десктопные приложения). Та сборка Qt Creator официальная, которую я ставил (2.3), по умолчанию почему-то десктопные части не устанавливала.

4. В следующем окне снимите галочку с пункта «Создать форму«.

5. В следующем окне можно ничего не менять. И жмем кнопку «Завершить«.

Редактирование файла проекта

6. Отредактируем файл проекта (у нас это Example.pro):

И добавим к строчке «QT += core gui» слово «declarative«. В итоге получим строчку:

Создание QML проекта

7. По папке с проектом в Qt Creator щелкаем правой кнопкой и идем к пункту «Добавить новый. »

8. Выбираем слева «QML«, а справа «Файл QML«.

9. Назовем его «main«.

10. Следующее окно без изменений.

11. В результате получим файл «main.qml» с текстом:

Создаем файл ресурсов

12. По папке с проектом в Qt Creator щелкаем правой кнопкой и идем к пункту «Добавить новый. «

13. Выбираем слева «Qt«, а справа «Файл ресурсов Qt«.

14. Назовем его «res«.

15. Следующее окно без изменений.

В результате получим файд «res.qrc«

16. Добавим префикс. Для этого щелкнем по кнопке «Добавить«, а там щелкнуть «Добавить префикс«.

17. Измените текст префикса на «/«.

18. Добавим наш QML файл. Для этого щелкнем по кнопке «Добавить«, а там щелкнуть «Добавить файлы«.

19. И выберем наш файл «main.qml«. И файл добавится к ресурсам нашего приложения:

Если сейчас запустим наше приложение, то qml пока не увидим:

Редактирование исходников

Теперь займемся подключением qml, чтобы он заработал.

20. Перейдем к редактированию файла «mainwindow.h» (находится в заголовочных). Он имеет пока вид:

Поменяем его на такой вид:

21. Теперь займемся редактированием файла mainwindow.cpp. Он имеет пока вид:

22. Запускаем наше приложение и получаем белое окно. Наш QML заработал.

Написание приложения

Теперь мы можем перейти к написанию непосредственно приложения, которое будет решать нашу задачу.

Построение интерфейса.

23. На данный момент main.qml выглядит так:

Отредактируем его, изменив главный прямоугольник-окно:

24. Добавим простейшую кнопку на нашу форму.

В результате main.qml примет вид:

Если мы запустим приложение,

то получим следующее:

25. Добавим строку ввода, куда пользователь будет вводить информацию с именем textinput.

В результате main.qml примет вид:

При запуске получим следующее:

26. Добавим поле вывода, куда программа будет выводить ответ с именем memo.

В результате main.qml примет вид:

При запуске получим следующее:

Итак, мы описали интерфейс нашей программы.

C++ часть

27. При нажатии на кнопку пока ничего не происходит. Исправим это. Для начала установим взаимосвязь между QML моделью и C++ кодом. Для этого отредактируем файл mainwindow.cpp, а именно функцию MainWindow, добавив строчки:

В результате получим:

29. Пусть у нас кнопка из QML будет вызывать С++ функцию под произвольным именем FunctionC. Объявим ее в mainwindow.h в классе в разделе public:

В результате получим:

Обратите внимание на ключевое слово Q_INVOKABLE. Именно она делает видимой функцию для QML.

30. Теперь опишем нашу функцию в mainwindow.cpp:

31. Ну и наконец добавим нашу функцию в обработчике нашей кнопки QML в файле main.qml. Обработчик действий мыши сейчас выглядит так:

Теперь же он станет таким:

Обратите внимание на то, что функцию вызываем через window.

Вот и всё! Теперь запускаем программу и нажимаем на кнопку. Если Вы всё сделали правильно и я не допустил ошибок, то Вы увидете:

Ссылка на исходники: Скачать.
Ссылка на исполняемый файл: Скачать.

Источник

Qt + QML на простом примере

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

Это будет минималистичное приложение, cмысл его простой — при нажатии на любую клавишу на клавиатуре на экране будет появляться случайное изображение и будет проигрываться, опять же, случайный звуковой эффект.

Пользовательский интерфейс будет полностью реализован на QML, программная часть на Qt.

Для тех, у кого Qt еще не установлен, заходим на страницу загрузки qt.nokia.com/downloads и в разделе «Qt SDK: Complete Development Environment» скачиваем бинарники для своей платформы. И, собственно, устанавливаем.

В новом окне вводим название проекта, указываем путь к проекту, жмем Далее.

В следующем окне снимаем галочку Создать форму, она нам не пригодиться, Далее. И в последнем просто нажимаем кнопку Завершить. Все, каркас нашего приложения создан.

Первым делом добавим модуль qt-declarative к нашему проекту, для этого, в файле проекта (4Toddler.pro), к строке

class MainWindow : public QDeclarativeView
<
.
>

От реализации конструктора отрежем, ставшую ненужной, инициализацию базового класса QMainWindow(parent).

Если сейчас собрать и запустить проект то мы увидим пустое окно. Так и должно быть, т.к. мы еще не создали и не инициализировали Qml интерфейс.

Читайте также:  не могу зайти на сайт единый урок рф что делать

Добавим в проект новый QML файл, для этого щелкаем правой клавишей по проекту

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

Rectangle
<
// Идентификатор, по нему будет происходить
// обращение к свойствам этого элемента
id: canvas;

// Цвет фона, черный
color: «black»

// Изменять размер под размеры
// родительского элемента
anchors.fill: parent

// Будет получать фокус ввода
focus: true
>

void MainWindow::Init()
<
// Путь к папке, содержащей QML файлы
QString contentPath;

#ifdef QT_DEBUG
// В отладочной версии это абсолютный путь к папке проекта
contentPath = «D:/MyProjects/QT/4Toddler» ;
#else
// В релизе это путь к папке, в которой расположено приложение
contentPath = QApplication::applicationDirPath();
#endif

setFocusPolicy(Qt::StrongFocus);
// Изменять размеры QML объекта под размеры окна
// Возможно делать и наоборот,
// передавая QDeclarativeView::SizeViewToRootObject
setResizeMode(QDeclarativeView::SizeRootObjectToView);

// Загрузить QML файл
setSource(QUrl::fromLocalFile(contentPath + «/main.qml» ));
>

Окно будет разворачиваться на весь экран. Прежде, чем запускать приложение, давайте добавим кнопку, с помощью которой можно будет закрыть окно. Забегая вперед скажу, кнопок в окне будет две, для того, чтобы не писать несоклько раз один и тот же код добавим к проекту новый QML файл, и назовем его WindowButton.

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

// Область, обрабатывающая «мышиные» сообщения
MouseArea
<
// Действует в пределах всего
// элемента Image
anchors.fill: parent

// При нажатии вызвать метод callback
onClicked: callback()
>
>

// Элемент позволяющий
// распологать элементы горизонтально
Row
<
// Правый край элемента выравнивается
// по правому краю родительского элемента
anchors.right: parent.right;
// Отступ справа, 4 пикселя
anchors.rightMargin: 4;
// Верхний край эелемента выравнивается
// по верхнему краю родительского элемента
anchors.top: parent.top;
// Отступ сверху, 4 пикселя
anchors.topMargin: 4;

// Отступ между элементами
spacing: 4

WindowButton
<
// Кнопка возова диалога «О программе»
id: about;

// Путь к файлу с изображением
// в данном случае иконка лежит в той же папке,
// что и QML файл
source: «about.png» ;

// Метод, который будет вызываться
// при нажатии на кнопку левой клавишей мыши
// onClicked: callback()
function callback()
<
>
>

WindowButton
<
// Кнопка закрытия окна
id: exit;

Чтобы то, что мы сделали заработало нам осталось реализовать оба метода callback для каждой кнопки. Для закрытия окна мы вызовем метод Quit, который реализуем в классе окна. Для этого в объявление класс добавим

Обратите внимание, что вызывать можно только те методы, которые объявлены как Q_INVOKABLE, т.е. от же метод Init, главного окна вызвать не удастся.

Готово, запускаем, видим черный экран, все, что сейчас мы можем сделать это закрыть окно, нажав на кнопку exit. Нажали и видим, что состояние кнопки при наведении курсора и при нажатии никак не меняется, выглядит как «неживая». Оживим ее, добавив состояния:

Image
<
.
states:[
State
<
// Произвольное название
name: «hovered» ;
// Указание на то, когда элемент переходит в это состояние
// в данном случае когда нажата левая кнопка мыши
when: mouseArea.pressed;
// Какие свойства будут изменяться в этом состоянии
// в данном случае это будет прозрачность
PropertyChanges < target: button; opacity: 1;>
>,
State
<
name: «normal»
// В это состояние элемент будет переходить
// когда левая кнопка мыши не нажата
when: mouseArea.pressed == false ;
PropertyChanges < target: button; opacity: 0.7; >
>
]
>

Элемент может переходить в определенное состояние как автоматически при выполнении условия, указанного в when, так и вручную, путем изменения свойства state.

Запустили, нажали, прозрачность изменяется, уже лучше, но не хватает плавности. Добавим следующий код:

Image
<
.
Behavior on opacity
<
// Анимация с шагом в 100 миллисекунд
// Раз в 100 миллисекунд прозрачность будет изменяться
// на 0,1
NumberAnimation < duration: 100 >
>
>

Behavior очень полезный элемент для создания анимаций, позволяющий указать то как будет меняться указанное свойство, в данном случае прозрачность кнопки.

Запускаем и смотрим, совсем другое дело, плавный переход от полупрозрачного к непрозрачному состоянию.

Окно о программе будет реализовано полностью на QML. Это будет модальное окно, которое будет появляться при нажатии кнопки about. При щелчке левой клавишей мыши в любом месте окна оно будет исчезать. Добавим новый QML файл About.qml в проект.

Я приведу сразу весь код этого окна с пояснениями

// Главный элемент для диалогового окна
Rectangle
<
id: about

// Функция для отображения окна
// изменяет прозрачность главного элемента
function show()
<
about.opacity = 1;
>

// Функция для закрытия окна
function hide()
<
about.opacity = 0;
>

// Прозрачный задний фон
color: «transparent»
// Полностью прозрачен по умолчанию
opacity: 0

// Ширина и высота устанавливаются равными
// ширине и высоте родительского элемента
// в данном случае это элемент с id: canvas
width: parent.width
height: parent.height

// Видимым элемент будет считаться если выполняется условие
// opacity > 0
visible: opacity > 0

// Дочерний элемент, создающий полупрозрачный фон
Rectangle
<
anchors.fill: parent

// Дочерний элемент создающий который является диалогом
// «О программе. »
Rectangle
<
id: dialog

// Ширина и высота являются фиксированными
width: 360
height: 230

Text
<
text: «4 Toddler»

// Выравнивание элемента по центру
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
>
>

Behavior on opacity
<
NumberAnimation < duration: 100 >
>

MouseArea
<
// Элемент полностью заполняет родительский элемент
anchors.fill: parent;

// При клике в любом месте прячем окно
onClicked: hide();
>
>

Это не просто присвоение ширины, если в процессе отображения будет меняться ширина родительского элемента, то и ширина дочернего будет перерасчитана. Не знаю как вас, а меня в процессе «ковыряния» QML эта особенность приятно удивила. Так же интересна следующая строка:

Читайте также:  можно ли хранить перекись водорода на морозе

Свойство может быть не только задано, но и вычислено.

Осталось добавить диалог и код для его отображения при нажатии кнопки about. В файл Main.qml добавим код, в конце элемента canvas

Для того, чтобы окно отображалось добавим строку

в функцию callback кнопки about

// Новое свойство объекта, необходимое
// для изменения состояния при удалении объекта
property bool remove: false
// При добавлении объекта
property bool show: false

opacity: 0;
fillMode: Image.Stretch;

states: [
State
<
// Состояние, в которое переходит объект
// тогда, когда нам нужно его удалить
name: «remove» ; when: remove == true ;
PropertyChanges < target: block; opacity: 0 >
StateChangeScript < script: block.destroy(1000); >
>,
State
<
// Состояние, в которое переходит объект
// тогда, когда нам нужно его отобразить
name: «show» ; when: show == true ;
PropertyChanges < target: block; opacity: 1 >
>
]

// Шаблон для создания новых элементов
var component = Qt.createComponent( «block.qml» );

// Максимальное количество элементов
var maxBlocksCount = 10;

// Массив, в котором будут храниться все эелементы
var blocksArray = new Array();

// Вызов функции, которая создаст новый элемент
// с указанными координатами
createNewBlock(x, y);
>

// Удалить лишние элементы
if (blocksArray.length > maxBlocksCount)
<
removeAllBlocks();
>

var newBlock = component.createObject(canvas);

if (newBlock == null )
<
return false ;
>

// Путь к файлу иконки доступен через свойство главного
// окна randomIcon
var iconFile = window.randomIcon;

newBlock.source = ( «Icons/» + iconFile);

newBlock.x = x;
newBlock.y = y;

// Переводим элемент в состояние show
newBlock.show = true ;

// Проигрываем случайный звуковой эффект
window.PlaySound();

// Удаление всех добавленных элементов
function removeAllBlocks()
<
for ( var i = 0; i true ;
>

Как видно из кода нам еще следует реализовать свойство randomIcon и функицию PlaySound главного окна.

Добавим свойство в объявление класса MainWindow

Q_PROPERTY(QString randomIcon READ RandomIcon)

И объявление функции

QString MainWindow::RandomIcon()
<
QStringList iconFilesList;
QString searchPath = m_ContentPath + «/Icons/» ;

QDir directory = QDir(searchPath);
QStringList filters;
filters «*.png» ;
directory.setNameFilters(filters);
// Получаем список файлов с расширением png
iconFilesList = directory.entryList(QDir::AllEntries);

// Получаем случайный индекс элемента
int fileIdx = qrand() % iconFilesList.count();

// Возвращаем название файла
return iconFilesList.at(fileIdx);
>

void MainWindow::PlaySound()
<
QStringList soundFilesList;
QDir directory = QDir(m_ContentPath + «/Sounds/» );
QStringList filters;
filters «*.wav» ;
directory.setNameFilters(filters);

// Получаем список файлов с расширением wav
soundFilesList = directory.entryList(QDir::AllEntries);
// Получаем случайный индекс элемента
int fileIdx = qrand() % soundFilesList.count();

// Получаем название файла
QString soundFile = m_ContentPath + «/Sounds/» + soundFilesList.at(fileIdx);
// Проигрываем файл
QSound::play(soundFile);
>

Почти все, осталось добавить обработчик нажатия клавиш в наш корневой элемент вызов фунции создания нового элемента. В начален файла main.qml сделаем видимым наш скрипт в файле main.qml

и сам обработчик внутри элемента canvas

На этом все — можем запускать и любоваться.

Как я и обещал программа является простой, но, на мой взгляд, это достаточно интересная «игровая» площадка для тех, кто только начинает изучать QML. Нет предела совершенству, кто знает, может кто-нибудь разовьет ее во что-то более стоящее.

Источник

QML — больше, чем просто GUI

Пятница, как известно, — конец рабочей недели, лучшее время для развлечения и игр. А лучшие игры — это те, которые увлекательны, в которых надо немножко подумать, и в которые можно сыграть с друзьями. Одну из таких игр я и решил написать.

Этот пост не является очередным переводом или вольным изложением разнообразных QML Howto и Quick Start. Скорее, это описание подводных камней, с которыми можно столкнуться при написании реального приложения.

Когда Qt Quick/QML только было заявлено, от Нокии звучали слова, что «в перспективе не только пользовательский интерфейс будет писаться на Qt Quick, но и вся логика несложных приложений будет написана на яваскрипте, программистам не потребуется написать ни строчки кода на плюсах». Заявление было ещё более провокационное, чем мой заголовок, и сразу меня заинтересовало: я решил попробовать написать несложную игру без единой строчки кода на плюсах.

Об остальном мы узнаем под катом.

Версия первая, или война с драг-н-дропом

В качестве отправной точки была выбрана игра Цаар — настольная логическая игра для двух игроков. Я искренне надеюсь, что моя коварная реализация данной игры не вызовет негодования правообладателей, но тем не менее рекомендую заинтересовавшимся её купить — в живом виде она куда интереснее, чем в моём исполнении.

А мы возвращаемся к разработке. Первым делом я десять минут созерцал игровое поле (на рисунке сверху): во всех приличных играх оно, как известно, прямоугольное. По истечении десяти минут я сказал: «Ага!», дополнил картинку узлами так, чтобы образовалась прямоугольная сетка, после чего написал функцию для проверки, существует ли узел на самом деле.

Я так подробно расписываю свои экзистенциальные метания и так мало привожу кода, чтобы прям сейчас добавить: это самые большие проблемы, с которыми я встретился в процессе. Это действительно так. Спозиционировать поле на форме, сгенерировать и расставить фишки, сделать самодельные кнопки и вывод статуса — нет проблем! Анимировать перемещение фишек — 2 строчки! Разрешать и запрещать игроку двигать различные фишки в зависимости от фазы хода — всё это в QML делается настолько элементарно, что я могу только предложить почитать официальный мануал с примерами. К окончанию работы, js-файл со всей основной логикой, включая пустые строки и комментарии, занимал аж 173 строки или 6 функций.

Ах нет, пожалуй, я вспомнил один момент, который меня изумил и вынудил написать костылик. Этот момент называется: drag’n’drop. Да, это звучит странно, но драг-н-дроп в чуть менее, чем полностью графическом тулките сделан хреново. «Таскать» можно, оказывается, не элемента, а MouseArea, который на нём лежит. Единственное, что мы можем — это определить, какими кнопками можно жмякать, и какие ограничения по координатам у нас есть. Нельзя, как при работе с системой, обработать событие «в меня чем-то кинули, что это», нельзя разрешить кидаться элементом только в определенные объекты. Можно только обработать события pressed и released. Дальше крутись как хочешь. А в примерах, если мне не изменяет память, такими глупостями вообще занимаются только со всякими Grid’ами и List’ами, никаких тебе произвольно спозиционированных элементов. Видимо из-за этого, кстати, сказать элементу «мне то, как тебя кинули, не понравилось, вернись на место», тоже нельзя. Я же говорю, разработчики только о разборе RSS думали.

Читайте также:  Упдг log point что это

Поэтому пришлось поступать следующим образом. Свойством элемента, очевидно, являются не его координаты на экране — x и y — а позиция на доске. Координаты высчитываются исходя из позиции. При событиях pressed и released мы запоминаем исходную позицию и вычисляем, в какую новую пытались кинуть элементом. После этого вызываем функцию, отвечающую за перемещение элемента. Если функция говорит нам, что перемещение невозможно, нам надо сделать с элементом что? Правильно, вернуть в исходную позицию. Смотрите внимательно за руками:

Видите это присваивание минус единицы? Ага. Дело в том, что в QML, если присвоить свойству то значение, которое в нём уже лежит (oX и oY), то движок считает, что свойство не изменилось, и не пересчитывает всё, то что с ним связано, в нашем случае это абсолютные координаты на экране. Приходится присваивать некоторое заведомо отличающееся значение, и только потом исходное.
Сама реализация драг-н-дропа выглядит вот так:

И вот на этом все проблемы действительно закончились. В игру можно было поиграть, выиграть за белых, выиграть за чёрных. Но — на одном компьютере. Это было скучно, я жаждал игры по сети с друзьями. И тут на сцену выходит вторая итерация разработки, гораздо более интересная.

Где в этот момент я начал задумываться и о третьей проблеме, но пока до неё ещё не дошло, мы поговорим о сети.

Как я обнаружил, в QML очень бедная и грустная поддержка работы с сетью. У нас есть Ajax-запросы из javascript-движка (причём, только асинхронные), и у нас есть активно измусоленный во всех примерах XmlListModel. Мне не хотелось бы верить, что весь QML был создан исключительно для лёгкого разбора RSS-потоков.

Как бы то ни было, забегая вперёд, скажу, что самой наглядной иллюстрацией бедности работы с сетью в QML является следующая строчка:

Если коротко, я хотел бы при закрытии игры отправлять на сервер сообщение, что я отключился и сессию можно убивать. Проблема вся в том, что при приходе сигнала я создаю асинхронный ajax-запрос, «отправляю» его, а дальше… а дальше наш цикл событий (event loop) успешно продолжает работу и штатно завершает работу программы — ведь причиной сигнала был нажатый крестик в углу окна. Вуаля! Запрос никогда на самом деле не успеет дойти до сервера. Никогда. Но я пытаюсь, я верю в лучшее.

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

Я перерыл интернет, я обнаружил инструкцию — принудительно сменить кодировку ответа на x-custom-charset — я обнаружил, что js-движок в Qt это не позволяет, и сменил кодировку прямо на сервере. После этого я скачал готовую библиотеку BinaryReader.js, которая уверяла, что способна читать текст по байтам и попробовал читать результат ещё и ей. Всё было тщетно — JS упорно отдавал мне 0xff вместо моего байта. На своё счастье я обнаружил, что индексы всех разрешенных для фишек ячеек — чётные. Я стал делить их пополам при передаче, и это позволило читать данные, как положено. В итоге код оброс ещё всего одним компонентом на 170 строк, который взаимодействовал с сервером и позволял насладиться полноценной сетевой игрой, а я подошёл к последней проблеме ­— о ней сразу после рекламы.

Версия третья, или куда пихать?

Интерфейсы на QML проектируются действительно очень легко и быстро, даже такими интерфейсо-ненавистниками, как я.
На QML можно написать игру или приложение, работающее с онлайн-сервисом. Если аккуратно обогнуть спрятанные грабли, то простота и удобство вас очень приятно удивят.
При толике желания из всего кода можно сделать один приятный бинарник со всеми включенными ресурсами, который и распространять
Работа с сетью всё-таки хромает. Мне кажется, разработчики игр для мобильных устройств (особенно в свете пиара NFC и тому подобного) были бы счастливы, будь у них возможность нормально установить соединение между устройствами, не вылезая на уровень C++
Искоробочный пример в qtcreator — сломан. Это страшный минус. Когда неправильно работает приложенный к IDE хеллоуворлд, это кидает страшную тень на всю библиотеку. В данном случае это наезд в сторону разработчиков QtCreator, а не самой технологии. Тем не менее, имейте в виду. Возможно, в версиях более поздних, чем моя 2.2.1, эту проблему исправили.
Судя по отпиленному синхронному режиму в XMLHttpRequest и кривой работе с побайтовым чтением, у меня сложилось ощущение, что JS-движок в Qt местами ущербен. Будьте аккуратнее.
Желающие сыграть в эту замечательную игру могут прочитать правила (возможно, их русская версия от Игроведа будет понятнее), скомпилировать игру командой qmake && make, и сыграть — только помните, что вам нужен партнёр, который тоже подключится к серверу.
Пользователи 32-битной Ubuntu 11.10 (может, и других систем, не обещаю) могут без затей скачать архив: sorokdva.net/tzaar/tzaar.tar.gz и запустить уже собранный бинарник. Для работы нужен пакет libqtwebkit-qmlwebkitplugin.

И если кому-то вдруг показалось, что это я усиленно ругаю QML, то я напомню два момента. Первый: на QML я написал игру в свободное время за, в общей сложности, максимум 40 часов (на самом деле меньше). Второй: на традиционном Qt и с его работой с графикой я написать игру не смог. И это должно уже говорить само за себя. А я в общем-то не то чтобы неосилятор.

Источник

Строительный портал