Всем привет. Сегодня познакомимся с QML. Узнаем что это такое и с чем его едят. Создадим небольшое приложение с использованием данной технологии.
Небольшое отступление:
QML(Qt Meta Language) — декларативный язык программирования, основанный на JavaScript, предназначенный для дизайна приложений. Является частью Qt Quick, среды разработки пользовательского интерфейса, которая поставляется вместе с Qt.
В качестве примера декларативных языков можно привести SQL и HTML. Подробнее о QML можете почитать здесь: документация.
Начнем, пожалуй, с самого простого: создания окна. Создаем два файла base.qml и test.py следующего содержания:
base.qml
import QtQuick 2.0
Rectangle {
//задаем свойства нашему прямоугольнику
id:green_rectangle
width: 250; height: 250
//цвет нашего прямоугольника
color:"green"
//аналогично свойству border-radius
radius: 7
}
test.py
import sys
# Класс QUrl предоставляет удобный интерфейс для работы с Urls
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QWidget
# Класс QQuickView предоставляет возможность отображать QML файлы.
from PyQt5.QtQuick import QQuickView
if __name__ == '__main__':
app = QApplication(sys.argv)
# Объект QQuickView, в который грузится UI для отображения
view = QQuickView()
view.setSource(QUrl('base.qml'))
view.show()
app.exec_()
sys.exit()
Код файла test.py должен быть вам полностью понятен, но если все же он вызывает у вас трудности, рекомендую пройти курс по PyQt5 здесь: https://pythonworld.ru/gui/pyqt5-firstprograms.html
Собственно это и есть простейший пример работы с qml, на выходе мы получим окно, размером 250X250 залитое зеленым цветом:
В QML, основным видимым элементом является элемент Rectangle. Элемент Rectangle имеет свойства для управления внешним видом и местоположением элемента, которые мы можем ему задавать, например, такие:
id: (уникальный идентификационный номер, нужен для обращения к объекту)
x: y: (отступы от родителя в px)
width: height: (ширина и высота)
color: (цвет заливки)
border.color: (цвет границы)
border.width: (ширина границы)
radius: (аналогично border-radius)
Другие свойства мы рассмотрим чуть позже.
Немного усложним задачу: создадим окно в котором будет прямоугольник с надписью: "Hello World":
Rectangle {
id:rec_main
width: 300; height: 300
color:"#fff"
radius: 7
Rectangle {
id:rec_green
width: 150; height: 150
color:"green"
radius: 7
border.color: "#0000FF"
border.width: 5
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
Text {
id: helloText
text: "Hello world!"
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: 10; font.bold: true
}
}
}
Теперь мы получим такой результат:
Здесь мы центрируем по вертикали и горизонтали наш объект относительно родителя anchors.verticalCenter: parent.verticalCenter,anchors.horizontalCenter: parent.horizontalCenter. Parent позволяет обратится к родителю, в нашем случае родителем объекта Text является Rectangle с id:rec_green.
Вообщем теперь вы должны понять, что интерфейс на QML строится на иерархии объектов. В нашем случае это выглядит так:
Сделали прямоугольник с надписью. Хм… Пока это мало напоминает полезный интерфейс, давайте добавим кнопку по клике на которую в консоль будет выводится надпись: "Hey Programmer".
Немного изменим код, теперь он будет выглядеть так:
import QtQuick 2.0
Rectangle {
id:rec_white
width: 300
height: 300
Rectangle {
id:btn_green
width: 80
height: 40
color:"green"
radius: 7
border.color: "#0000FF"
border.width: 1
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
Text {
id: btn_green_label
text: "Click me"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Hey Programmer");
}
}
}
}
В итоге получаем:
Здесь мы добавляем объект MouseArea, позволяющий работать с мышью.
anchors.fill: parent — говорим, что вся область родителя будет задействована.
onClicked — событие нажатия на кнопку. В нашем случае, вызывается функция, выводящая в консоль: 'Hey Programmer'.
На этом, пожалуй, сегодня и закончим. В следующих статьях разберем qml более подробно.
Пока вы, возможно, не видите преимуществ использования qml, но когда мы познакомимся с этим замечательным инструментом подробнее, вы поймете какой он удобный и функциональный.
Спасибо за внимание. Если у вас остались вопросы задавайте их в комментариях. Надеюсь статья была вам полезна.
CJay
У стороннего наблюдателя, глядя на все эти зелёные прямоугольники с синим контуром и закруглёнными краями, может возникнуть ассоциация с рисованными на flash интерфейсами. И может показаться, что это что-то несерьёзное.
Но на самом деле, на qml очень хорошо получается сделать компоненты в том же стиле Material Design. Так что, на мой взгляд, если знаешь питон и нужно писать GUI приложение, стоит обратить внимание на эту технологию.
Tantrido
Красиво! Может опубликуете код и статью? :)
CJay
Статью писать смысла особо нет, так как в официальной документации сказано обо всём том же.
А код… залил на Bitbucket. Но код очень далёк от совершенства (заранее предупреждаю):
https://bitbucket.org/mmalanuck/qmaterial
Так же пытался описать свои компоненты в виде документации, может тоже будет интересно пробежаться глазами:
https://mmalanuck.bitbucket.io/material_ui/
Antervis
не только в стиле Material. Там есть возможности стилизации компонентов, есть Qt.labs.platforms для нативно выглядящих компонентов. Можно код шейдеров писать прямо в ShaderEffect. Его возможности много превосходят старые добрые QtWidgets.
Всё самое интересное начинается, когда перекладываешь архитектуру приложения на QML, а бекенд-классы пишешь на с++ (хотя и на питоне можно) и просто регистрируешь. Получается простой, модульный и переиспользуемый код
el777
Вот это интересный вариант!
Интересно посмотреть насколько сложный QML для этого пришлось написать.
Я 2 года назад сделал приложение на Python3+Qt5. Интерфейс несложный, но на QML выходила очень сложная реализация (хотел сделать кнопку-прогрессбар, на которую можно и тыкать, и которая сразу же показывает прогресс своей задачи), в итоге оказалось проще сделать на QWidget и стилизовать QSS.
CJay
Несложный. Процесс создания компонент немного напоминает работу с React на js. Ссылку на исходники я написал в комментарии чуть выше.
delvin-fil
Это начало? Будет серия?
Не просто заинтересовало — заинтриговало!
Жду продолжения.
Спасибо за статью!
FUNNYDMAN
Спасибо большое за комментарий. Да это начало серии уроков.
CJay
А почему вы объект
QQuickView()
присвоили переменнойappLabel
? Почему это appLabel? Label — это же подпись. Может лучше было быview = QQuickView()
?FUNNYDMAN
Спасибо за Ваш комментарий. Так, конечно, будет понятнее. Поправлю.
Ashiru
Спасибо за статью!
С нетерпением жду продолжения :) Будет интересно посмотреть на взаимодействие QML с самим питоном.
vodan
Спасибо за статью, где про это можно почитать что надо установить? Из статьи не совсем понятно что должно быть установлено (
FUNNYDMAN
Спасибо за комментарий. Вы должны установить python 3.x и PyQt5.