Файл qml что это

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

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

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

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

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

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

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

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

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

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

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

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

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

8. Выбираем слева «QML«, а справа «Файл QML«.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

9. Назовем его «main«.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

10. Следующее окно без изменений.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

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

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

13. Выбираем слева «Qt«, а справа «Файл ресурсов Qt«.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

14. Назовем его «res«.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

15. Следующее окно без изменений.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

17. Измените текст префикса на «/«.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

Если сейчас запустим наше приложение, то qml пока не увидим:
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

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

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

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

22. Запускаем наше приложение и получаем белое окно. Наш QML заработал.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

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

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

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

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

Если мы запустим приложение,
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это
то получим следующее:
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

При запуске получим следующее:
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

При запуске получим следующее:
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл 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.

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

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

Источник

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

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

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

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

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

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

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

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

class MainWindow : public QDeclarativeView
<
.
>

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

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

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

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл 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 что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл 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 что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

Источник

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

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

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

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

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

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

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

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

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

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

Поэтому пришлось поступать следующим образом. Свойством элемента, очевидно, являются не его координаты на экране — 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 что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

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

Интерфейсы на 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 и с его работой с графикой я написать игру не смог. И это должно уже говорить само за себя. А я в общем-то не то чтобы неосилятор.
Файл qml что это. Смотреть фото Файл qml что это. Смотреть картинку Файл qml что это. Картинка про Файл qml что это. Фото Файл qml что это

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *