Pull to refresh

Comments 78

Насчёт отсутствия примеров — Вы зря. Вот Вам Qt Developer Guides. Там отличный туторил по Qt Quick Application Developer Guide for Desktop. Так есть и по Programming with Qt Quick for Symbian and MeeGo Harmattan Devices.
Не нашел там описания взаимодействия QML и С++. Подробного описания начальных шагов тоже. Эта статья для самых новичков в этой среде — для тех, которые никогда Qt в глаза не видели, а программировали в других средах. И они, установив Qt Creator, не понимают, как что-то создать рабочее. При этом я ничего не говорю про уроки самого QML. Информации по этой области много.
Я не то чтобы имею что-то особо против этого примера. Пример хороший. Только вот идеологически он немного неправильный. Дело в том, что тут типичный пример где QML это frontend, а в C++ мы имеем backend и даже больше я скажу, что оно стоит того, чтобы использовать MVC где QML будет viewer, а в C++ классах будут располагаться controller и model, а общение между ними будет идти через сигналы и слоты.

И в первую очередь сигналы должен подавать фронтенд бекенду и в обратную сторону backend должен бы отдавать только сигналы с какими-то параметрами фронтенду, а не напрямую управлять им, как это сделано у вас.

Т.е., в конечном счете должно быть не memo->setProperty(«text», str+"+1="+str2) скажем, а emit memoText(value) и контроллеру уже должно быть пофиг как фронтенд распорядится тем, что ему дали… а вот общение контроллера и модели — тут да, тут имеет смысл прямые вызовы функций, но и то только иногда.
На мой взгляд вы пошли немного не с той стороны, нужно не QML встраивать в с++, а наоборот, на с++ делается как бы API будущей программы, а на QML+JS пишется весь GUI, который дергает c++ API, в основном это как правило различные модели да функции работы с базой и логикой. Код получается на порядок проще и чище.
Вместо вот такого onClicked: window.FunctionC()
Бросился в глаза у Вас, следующий участок кода:

Rectangle {
id: button //Имя кнопки
//Размещаем в центре
x: parent.width / 2 - button.width / 2;
y: parent.height / 2 - button.height / 2;


Это можно сделать гораздо удобнее. Вот пример:

Rectangle {
width: 200
height: 300
color: "Red"
Rectangle {
width: 50
height: 60
color: "Blue"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
}

Синий прямоугольник всегда будет по центру у меня. Посмотрите по очень важное свойво anchors. Например, тут.
Ох блин, опять новички жить учат.
Ну ок, ответьте мне пожалуйста на такие вопросы (я тоже новичок):

Та сборка Qt Creator официальная, которую я ставил (2.3), по умолчанию почему-то десктопные части не устанавливала.

Странно это, как они забыли в официальную сборку IDE(!) положить библиотеку и компилятор, совсем глупые наверное, хотя я где-то читал, что IDE != библиотека + компилятор + редактор и все нужно ставить отдельно или использовать QtSDK, подскажите, прав ли я?

Мы добавили #include <QtDeclarative/QDeclarativeView>, #include и др, добавили namespace, добавили ключевое слово explicit, и главное добавили QDeclarativeView *ui.
А зачем мы все это добавили, а если не добавить слово explicit, работать не будет? А без namespace?

        x: parent.width / 2 - button.width / 2;
        y: parent.height / 2 - button.height / 2;

Ох как сложно, а мне рассказывали, что в QML есть какие-то лайоуты c которыми так удобно элементы расставлять. Обманывали наверное.

Обратите внимание на ключевое слово Q_INVOKABLE.

Я открыл стандарт С++ и не нашел там такого ключевого слова, где вы его взяли, а без него нельзя обойтись?

Впрочем ладно пока хватит вопросов.
Q_INVOKABLE
Q_PROPERTY

и ряд других макроопределений это ключевые слова для прекомпилятора от Qt, который на основании этих меток строит метаобъектную систему. Подробнее в документации: doc.crossplatform.ru/qt/4.6.x/moc.html
То есть все-таки это макросы а не ключевые слова?
Ну и конечно, мне было бы интересно послушать ответ автора статьи, в том числе и на вопрос, а нельзя ли обойтись без Q_INVOKABLE
Можно, сделать эти методы слотами.
Основное отличие слота от метода помеченного как Q_INVOKABLE это то, что последний нельзя связать с сигналом.
Правда правда нельзя??? А если попробовать? ;)
Грешен, функционально идентичны, различие только семантическое.
Но все же, ИМХО, без острой необходимости все равно лучше не связывать =).
Эм. Q_INVOKABLE возвращает значение, а вот со слота его стрясти проблематично.
Если объявить слот не void'ом и вызывать его как простой метод то он прекрасно вернет значение, равно как если такой слот дернуть из QML как метод он также прекрасно вернет значение.
Да? А почему когда я пытался из яваскрипта стрясти со слота возвращаемое значение мне упорно возвращали undefined?
Это было из вебкита, но суть не меняется.
В QtScript оно всю жизнь замечательно работало. С этим как раз проблем нет.

Более того, можно любой слот вызывать по имени через QMetaObject::invoke и получить возвращаемое значение с использованием макроса Q_RETURN_ARG
>Q_INVOKABLE возвращает значение, а вот со слота его стрясти проблематично.

Да ладно? И что, вы хотите сказать, что я не могу вызвать слот как обычный метод и получить от него результат? Подумайте ещё раз :)

На самом деле даже через сигнал можно получить возвращаемое значение слота и присвоить его переменной. Просто пишем
int value = emit someSignal();

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

Для того, чтобы метод можно было вызывать из QML, он должен быть зарегистрирован в мета-системе Qt, что достигается либо через макрос Q_INVOKABLE, либо через объявление метода слотом.
Это не просто макросы в понимании C++. Их анализирует не компилятор а moc
По умочланию действительно десктоп не ставится, точнее не ставится компилятор MinGW. Нужно в начале установки щелкнуть малоприметную галочку «custom install» (или как-то так) и там добавить MinGW. Я тоже долго недоумевал, почему у меня на одном компе доступны десктопные проекты а на другом нет, хотя дистрибутив один и тот же:)
Много вопросов. Постараюсь ответить на все.
Странно это, как они забыли в официальную сборку IDE(!) положить библиотеку и компилятор, совсем глупые наверное

Я не говорил, что они забыли положить библиотеку и компилятор. Просто при установке, как верно отметил NeoCode, нужно поставить галочку, чтобы установились части для создания десктопных приложений. Если всё ставить по умолчанию, то вариантов создания приложения для десктопа не будет.

Мы добавили #include <QtDeclarative/QDeclarativeView>, #include и др… А зачем мы все это добавили

Это требуется для того, чтобы связать QML и С++. Вполне возможно, что есть и другие способы, но в этом нужны эти модули.

, добавили namespace
Здесь соглашусь с Вами. Можно обойтись и без этого.

главное добавили QDeclarativeView *ui.
Ну без этого мы не подключим этим способом qml.

Обманывали наверное.
Статья не ставила своей целью показать красивости и основные приемы QML. Для этого существуют множество статей. Интерфейс был не важен, а была поставлена четко задача, которая и решалась.
Ошибся с оформлением цитат.
>А зачем мы все это добавили, а если не добавить слово explicit, работать не будет?

Работать, разумеется, будет. Назначение explicit стоит вообще в стороне рассматриваемой проблемы. Его нужно указывать тогда, когда мы хотим запретить неявный вызов конструктора. Поясню лучше на примере:

#include <iostream>

class A {
public:
	A(int a) { _a = a; }
private:
	int _a;
};

class B {
public:
	explicit B(int b) { _b = b; }
private:
	int _b;
};

int main(int argc, char* argv[]) {
	A a1(1); // ok - вызывается конструктор
	A a2 = 2; // ok - неявно вызывается конструктор (нет, не оператор копирования, как часто думают)
	
	B b1(1); // ok - вызывается конструктор
	B b2 = 2; // compiler error - попытка неявного вызова конструктора, помеченного как explicit

	return 0;
}
> красивая и радует глаз

>
image


facepalm.ui
По красивостям QML существует множество других статей. Цель этой статьи было показать пример связки.
Я видел этот пример. Честно пытался несколько раз повторить его. Ни разу не получилось. Ошибки вылазят.
Простите, но что это за херня? Я не буду тонко троллить как «некоторые». Я так скажу.

1. Нахрена нужен Widgets проект? Почему мы не стали делать quick проект?
2. Зачем нам QMainWindow?
3. Зачем нам ресурсы? Вернее они конечно нужны, но нафига их выставлять как непреложную истину? Для подобных хауту и различных тестов (да и в некоторых приложениях) можно обойтись без них
4. Зачем так страшно искать qml объекты в плюсах? нельзя было сделать через сигнал-слот? То есть вызывается метод (хотя это тоже можно сделать через сигнал-слот, но бог с ним, пусть будет invoke напрямую) с параметром, в котором лежит текущее значение инпута. Что-то то там делается и испускается сигнал с нужным значением memo, который ловится в qml. Ведь так гораздо приятнее выглядит и удобнее потом править если что.
5. Ну и да. хауту по кумлю даже на хабре уже вполне приличное количество. Про внешний интернет я вообще молчу
1. вначале искал этот способ через quick. Но опять так и не нашел способа взаимодействия с С++. Скорее всего плохо искал. Но не нашел. По крупицам собрал рассмотренный в статье пример. Буду рад, если покажете вариант, как решить поставленную в начале статьи задачу через quick проект.
2. А как иначе?
3. как минимум нужно увидеть qml файл. Можно и по другому, но ресурсы потом всё равно пригодятся для рисунков и др.
4. Покажите, пожалуйста, пример.
5. Про QML я ничего не говорю. А вот про взаимосвзяь QML и С++ для новичков нет. Точнее есть, но ни один из вариантов у меня по тем или иным причинам не заработал. Или вообще не запускается (всё перепроверялось на несколько раз) или не всю приводится и откуда то в коде возникает переменная, о которой до этого ничего не говорилось. Если бы получилось, то этой статьи не было. Возможно я просто тупой.
1. Ну дак через qmlRegisterType, через проперти контекста и прочее можно устроить взамоидействие. В чем проблема то? Создать еще один класс — наследник qobject?
2. Ну например можно было в качестве топ левела выставить сам QDeclarativeView
3. Его можно увидеть из самой файловой системы через относительный путь. Для подобного хауту этого способа за глаза хватит
4. Пример чего? Отловки плюсового сигнала в кумле? Ищите в ассистанте элемент Connections кумльный
5. В ассистанте есть очень хорошие статьи на тему взаимодействия
Есть же православные .ui, зачем этот велосипед?
Если вы немного не в теме о готовящемся Qt5, то сядьте, выпейте рюмочку чая и читайте
labs.qt.nokia.com/2011/05/09/thoughts-about-qt-5/
Вкратце о GUI — QML теперь основной способ создания интерфейса, а QWidget — модуль в отдельной либе…
Ужас. Чем оно лучше виджетов? Что-бы 2 поля и кнопку написать, целая страница кода требуется.
Тем, что это даже не компоненты полноценные, а кирпичики. Из них можно собрать что угодно и любой сложности, с максимальной степенью кастомизации. У них планируется требования малые сделать к системе, чтобы можно было с легкостью на всяких кофеварках запускать и тд :)
>>Из них можно собрать что угодно и любой сложности, с максимальной степенью кастомизации.
Так и запишем: свистоперделки.
>>У них планируется требования малые сделать к системе
Там же всё на векторной графике, так что совсем наоборот.
графические ускорители давно ставят куда ни попадя. Тот же raspberry pi за 25 баксов выдает около 1к фпс на qt5&qml
Стоп. Сначала вы говорите, что qml пилят под кофеварки, а теперь, что кофеварки под qml. В общем, ничего кроме свистоперделок вроде прозрачности и анимации в этом велосипеде нету.
я? я вообще молчу, чо :D
Никто кофеварки под кумль не пилит. Я говорил про нынешние технические возможности, которые позволяют без проблем реализовать красивый и приятный (не как в посте, а действительно приятный) интерфейс без лишних затрат на разработку и поддержку этого интерфейса
Простите, перепутал. А оно уже умеет хотя-бы QPushButton, зависящий от QT-темы одной строчкой?
умеет. В десктопных компонентах
import QtDesktop 0.2

Button {
text: qsTr("Click Me")
onClicked: foo.bar()
}
«Свистоперделки» — нужная штука, можно шикарный GUI сделать, степень кастомизации и простота анимации на высоте! Технология шикарна!

>> Там же всё на векторной графике, так что совсем наоборот.
Почитайте про Scenegraph
>>«Свистоперделки» — нужная штука, можно шикарный GUI сделать, степень кастомизации и простота анимации на высоте! Технология шикарна!
Стена там --->
Да я с вами согласен, нативный Motif — лучший на все времена.

image
В том-то и дело, что приложение на виджетах в разных темах оформления будет выглядеть однородно. А qml продвигает совершенно противоположную идею быдлогуестроения, где каждое приложение имеет свой стиль и своё оформление. Вот вы-бы смогли работать в таком зоопарке?
И зачем, когда на qtgui это всё будет занимать в 2 раза меньше кода?
Да с Вами невозможно разговаривать, неужели дело только в длине кода?!

Попробуйте написать анимацию на C++ и на QML, почувствуете разницу!
А еще просто откройте для себя QtQuick 3d, ну просто (совсем совсем) никакого сравнения C++ кодом… Если уж вас так волнует его длина…
Анимация и 3d в системных приложениях не нужны. Роль гуя — удобное представление данных и элементов управления. Всё остальное для 13-летних девочек.
115-летний мальчик, ты бы хоть посмотрел на то как сейчас выглядят UI мобильных осей или последних десктопных осей (macosx 10.7, win7, kde4, gnome3, unity). А потом бы уже говорил. Ну очень толсто же
>>kde4, gnome3, unity
Цепляют тему gtk+ и qt
>>win7
цепляют тему винды
>>macosx
Не видел в живую, но, судя по скриншотам, там все приложения стилизованы одинаково.
А если вы про анимацию или 3d, то ни разу не видел этого ни в gtk+-, ни в qt- приложениях и это меня очень радует.
Человек, остановись, признай свою неправоту, а не продолжай сам себя припирать к стенке. Иначе скоро выяснится, что ты и приложений на Qt не видел ни одного…
А что я неправильно-то сказал? Насколько я понял, ваш единственный аргумент в пользу qml — анимация и 3d. На что я привёл свою точку зрения:
>>Роль гуя — удобное представление данных и элементов управления. А анимация только мешает восприятию данных и выбивается из общего стиля окружения.
С чем конкретно вы не согласны?
анимация (ясен пень правильная и не навязчивая) облегчает восприятие данных. Делает его более естественным
у меня тряпочки закончились чтобы жир с экрана стирать

ты не видел анимаций в приложениях? Лол. Анимации везде используются сейчас. Истинное 3д да, не используется. Но шейдеры очень хороший инструмент для создания сложных анимаций
>>ты не видел анимаций в приложениях?
Сложнее смены иконки при наведении или клике? Нет. И, повторюсь, рад этому. Долго искал на ютубе видео, где приложение стартует около 20-30 секунд, показывая юзеру всевозможные красивости, но, к сожалению, не нашёл. Так вот, если вы стремитесь к такому десктопу — пожалуйста. А я всё-же надеюсь на благоразумность qt-разработчиков.
слушай, тролль, а ты разницу между ненавязчивой естественной анимацией и 20-30 секундами вступительного ролика ваще чуешь? или нет?
Фу, как невежливо. У нас с вами разное видение современного десктопа, так-что предлагаю закончить спор, оставшись каждый при своём мнении. Это всё-равно, что спорить об искусстве. Для меня ненавязчивая анимация заканчивается на смене стиля при наведении мыши.
невежливо это троллить так толсто, как делаешь это ты. Я с трудом буквы твоего коммента через жир из монитора вижу
Парень, скажи это Стиву, царство ему небесное…
Это вы мне так тонко смерти пожелали? =)
Стив умел делать деньги на хомячках. И делал он это отчасти из-за красивостей и анимаций, да.
Неужели Вы на что-то согласились…
да ладно чо. Покормить иногда забавно
Так и не понял чем автору не понравилось сразу создать «приложение QtQuick» и почему он не заглянул в примеры, там есть пара замечательных примеров на тему Extending QML with C++.
Я не понял этих примеров. Точнее не понял как решить задачу, которую перед собой поставил здесь. Я туп.
Отличный пример! Спасибо! Неохота вечером после работы еще ковыряться в англоязычном материале!
А люди, имеющие хороший опыт в разработке на Qt, прекрасно должны уметь читать не только код, но и заголовок. В котором русским по белому написано «QML и C++. Простой пример связки». Слово «Простой» тут с заглавной буквы даже написано)

А если есть мнение, что хабр не место для простых примеров, то надо объяснить, что существуют вещи типа github или bitbucket, которые индексируются не хуже Хабра, и что их можно использовать в разных целях, даже для того чтоб поделиться опытом, пускай и небольшим. А если надоело объяснять такие простые истины, то спросите себя: «Мне не надоело угнетать новичка, который недавно в чем-то сложном для него разобрался?»

Еще раз спасибо автору! Написал отличное дополнение к официальной документации и множеству примеров. Пишу без малейшего сарказма.

Отличная статья, мне и сейчас зашла. Но отсутствие всех буквально картинок разочаровывает.

Ну не было 10 лет назад на хабре Habrastorage. картинки пропадали в статьях не то что через 10 лет, а через полгода-год.
Sign up to leave a comment.

Articles