Как стать автором
Обновить

Комментарии 24

Очень похоже по духу RAD на Polymer, только он использует HTML (Web Components) вместо JSON и CSS Flex вместо anchors.
Вижу *QML, ставлю "+" =))

А если серьезно, ваш проект очень крут. Желаю удачи в развитии!

Офтоп.

Последнее время меня терзает вопрос, а почему собственно производители браузеров не хотят добавить нативную поддержку нового языка, похожего на QML, как альтернативу HTML в свои движки?

Это же было бы так круто — заменить весь этот ужас HTML/CSS/etc на новый JSON-подобый и декларативный стандарт! Тем более что есть готовый пример в виде Qt/QML.

Я понимаю, что сейчас активно пилится WebAssembly и когда он будет готов, то хоть весь Qt можно будет в браузере использовать, но все же это немного не то — не будет 99% веб-программистов/верстальщиков его юзать.
НЛО прилетело и опубликовало эту надпись здесь
Изначально html предполагался как human-readable.
Нынешние html'и даже браузеры не все понимают…
Изгначально html был языком разметки гипертекста, а не языком разметки приложений или вёрстки
Это же было бы так круто — заменить весь этот ужас HTML/CSS/etc на новый JSON-подобый и декларативный стандарт!
Так не будут делать, потому что уже есть 14 стандартов
Я чего-то не знаю про QML или вы заменили QML-ный синтаксис объявления методов на TypeScript-овый?
Разве? Вот ссылка на qml-ный синтаксис.

Мы поддерживаем и простой вариант, типа
method: { }
, с одной лишь оговоркой, что
function onFoo() { }
это метод onFoo, а не обработчик сигнала.
Ну ок, не заменили, а добавили. Тем не менее синтаксис новый (и на мой взгляд добавляет путаницу), причём на сайте в разделе с различиями с оригинальным QML я этого не нашёл.
Я видимо что-то не понимаю, в qml обработчики событий задаются так же как у нас. Просто мы синтаксически не разделяем эти две декларации, что позволяет задавать методы, если они не с onXyz начинаются. Визуально путаницы никакой нет.
reset : { this.model.reset() }
update: { this.model.update(this.range) }

Я, честно признаюсь, не исследовал оригинальный qml, насколько он строг в этом смысле.

На самом деле я просто хотел убедиться, что семантика Qt/QML в вашем PureQML сохранена. Но потом увидел вот это:


// ...
setPos(long, lat): {
    // ...
}
// ...

Для Qt/QML это в принципе невалидная запись, что меня и заинтересовало.


На мой взгляд разница между одной записью и другой всё же есть. Если я правильно понял, то для вас эти две записи эквивалентны:


function foo() { }

и


foo: { }

С одной стороны вторая запись слишком похожа на binding какого-то выражения к свойству foo. Окей, допустим, вы не стали делать различия между свойствами и методами (мемберы и есть мемберы, почему бы и нет). Но в Qt/QML есть другая штука. Вот эти две записи с его точки зрения эквивалентны:


propName: jsExpression

и


propName: { return jsExpression; }

Таким образом, если мы хотим забиндить ("забайндить" не звучит, так что буду называть это забиндить) на свойство не результат выполнения блока кода, а сам этот блок кода, то в Qt/QML мы пишем как-то так:


property var foo
// ...
foo: function() {
    // ...
}

или даже


foo: {
    return function() { /* ... */ };
}

В общем, немного сложно понять, что происходит.


С другой стороны вы, возможно, не стали делать различия между методами и обработчиками сигналов. Окей, тоже почему бы и нет. Фактически, единственное, что их у вас отличает, это наличие префикса on. На мой взгляд, это различие недостаточно явное. Например, предположим, у нас есть компонент Foo, описанный в Foo.qml следующим образом:


Item {
    foo: { 
        console.log("inner"); 
    }
}

Потом мы его используем как-то так:


Item {
    Foo {
        id: _foo

        foo: {  // переопределение метода, объявленного внутри
             console.log("outer");
        }
    }

    onSomeEvent: {
        _foo.foo() // выводит только "outer"
    }
}

В случае же с сигналами всё работает немного иначе. Допустим, Bar выглядит так:


Item {
    signal bar()
    onBar: { 
        console.log("inner"); 
    }
}

Потом мы его используем как-то так:


Item {
    Bar {
        id: _bar

        onBar: {  // пишем свой обработчик сигнала
             console.log("outer");
        }
    }

    onSomeEvent: {
        _bar.bar() // выводит сначала "inner", потом "outer"
    }
}

Другими словами, если бы вы позволяли объявить таким же образом метод, начинающийся с on, то была бы вообще полная неразбериха. А так только наполовину, на мой взгляд. Странно всё это :)

Можно подружить одним из двух способов:
1. Добавив стили в html файл, т.е. как обычно;
2. Добавить в рантайме через stylesheet._addRule().

Но проблему разъезжания можно, и это наверное даже проще, решить декларативно через context.system.layoutType или context.width, что-то вроде:
font.pixelSize: context.system.layoutType <= System.MobileL? 14: 18;

А как расположить visibility под широтой и долготой, если на одну строку не вмещается?


Нельзя же уменьшать размер шрифта до бесконечности, нечитаемо будет.

При желании зацепиться анкерами можно:
	Text {
		id: visibilityText;
		anchors.left: parent.left;
		anchors.bottom: parent.bottom;
		anchors.margins: 10;
		font.pixelSize: 24;
		color: "#fff";
		text: "Earth visibility: -";
	}

	// текст с координатами: долготой и широтой
	// текст прижимаем к левому нижнему краю
	Text {
		id: positionText;
		anchors.left: parent.left;
		anchors.bottom: visibilityText.top;
		anchors.margins: 10;
		font.pixelSize: 24;
		color: "#fff";
		text: "Lon: -<br>Lat: -";	// в текст можно вставлять html теги
	}

Теперь visibilityText прижат к левому нижнему краю, а positionText к левому краю но к верхей границе visibilityText
Можно сложить все это добро в Grid и тогда оно само перенесется, если не влезет. Или же руками руками навертеть логики разной степени безумности, типа:
anchors.bottomMargin: (visibilityText.width + latText.width) < context.width ? 20 : 0;

Или завернуть во FlexBox и доверить браузеру. Или крутить display.
Но грид, в данном случае, наиболее изящнен.
Сделал UI адаптируемым для мобильных телефонов, посмотреть можно тут
Теперь, чтобы открыть/закрыть OSD нужно нажать кнопку в верхнем левом углу:


Для десктопа логика осталась прежней

Спасибо, стало и красивее и понятно как это сделать!

Обычно для тестирования GUI framework я пытаюсь реализовать
следующую "простую" задачу:


в прямоугольник слева, вверху, шириной 1/5 от ширины окна приложения,
и высотой 1/5 от высоты окна приложения, вывести произвольное число от 0 до 999
шрифтом по умолчанию. Размер шрифта должен подбираться автоматически,
с помощью GUI framework, таким образом, чтобы максимально занять выбранный прямоугольник.


Насколько сложно это будет реализовать с помощью PureQML?

Если я правильно понял условия то код нужен такой:
Item {
	anchors.fill: context;

	Rectangle {
		width: 20%;
		height: 20%;
		color: "red";

		Text {
			font.pixelSize: parent.height;
			text: "42";
		}
	}
}

А результат будет такой:

Если я правильно понял условия то код нужен такой:

Да спасибо именно то, что я имел ввиду.


А ваши инструменты. типа ./qmlcore/build --boilerplate
проверяют валидность, что в данном контексте доступны данные свойства,
callbacks и подобные вещи?

Команда
./qmlcore/build --boilerplate

сгенерит простое Hello World приложение, чтобы собрать свой проект нужно просто позвать
./qmlcore/build

Насчет свойств, декларативные property проверяются, а вот сигналы нет
Этот фреймворк ещё поддерживается?

Я так понимаю, что под Windows проекты не собираются? На 7 и Python 2.7 возникают ошибки при сборке проекта — файл манифеста пустой, не указан какой-то параметр.
А какие ошибки у Вас возникают?
И да, фреймворк живой, как можете заметить это на гитхабе. И для винды даже собирали недавно exe-шник
Также у нас есть канал поддержки в телеграмме, куда Вы можете написать о Вашей проблеме, чтобы решить ее оперативно, если, конечно, еще не решили ее самостоятельно =)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории