Pull to refresh

Comments 55

PyQt это опять же — Qt. Лично по мне так он довольно сложен для понимания, особенно QML. Все-таки самый лучший способ писать интерфейс разметкой — это xml (и его расширения типа XAML и т.д.). А вот в json разметку еще и намешанную с js воспринимать очень тяжело.
XML легче читать чем json… Вы это серьезно?

В JSON даже комментарии нельзя вставлять, не говоря уже о схемах и прочем.
Для передачи данных да, он компактнее и, может, более читаем. Но для разметки, конфигов я предпочту XML.

В QML-то есть комментарии, безо всяких извращений вида <!--… -->
Комментарий в JSON — {...«node»:«нечто по этому узлу», «nodeCOMMENT»:«Комментарий»...}
это не комментарий

У JSON в плане использования как языка разметки есть фатальные недостатки — неименованые типы объектов и отсутствие встроенных текстовых нод. Из-за этого при определении списка элементов приходится писать что-то типа


{
  "@type": "StackPanel",
  "children": [
    {
      "@type": "TextBlock",
      "text": "Hello world"
    },
    {
      "@type": "Button",
      "text": "Click me"
    }
  ]
}

вместо


<StackPanel>
  <TextBlock>Hello world</TextBlock>
  <Button Text="Click me"/>
</StackPanel>

В QML это будет


ColumnLayout {
   Text {
     text: qsTr("Hello world")
   }
   Button {
     text: qsTr("Click me")
   }
}

Единственный косяк QML — возможность писать код прямо в разметке — так и поощряет быдлокодить и приходится каждый раз себя бить по рукам для разделения вида контролов и их логики

Это выглядит лучше чем json, но я бы не сказал, что лучше, чем XAML. Примерно одинаково и дело привычки. (хотя я бы в вашем примере еще комментировал закрывающие скобки, если большая вложенность)

QML позволяет быдлокодить примерно так:


Button {
     property int times = 0
     text: qsTr("Clicked %1 times").arg(times)
     onClicked: times++
}

Что в XAML получится кудааа длиннее. Но в то же время WPF заставит сделать аккуратно, а QML на все это пофиг. Поэтому от мало-мальски сложного проекта на QtQuick начинают течь слезы, если только разработчик не заставил себя следовать какой-нибудь методологии (вроде Flux)

В UWP Можно сделать примерно так:
  <Button Click="Onclick" Content="{x:Bind GetClickCount()}"/>

А логику уже в codebehind, если это логика UI. Ну или во вьюмодель если бизнес.

Кстати, в андроидовском axml можно тоже в биндингах делать некую логику. Отличная замена конвертерам.

Но вот полностью функции писать в верстке. Сомнительное это преимущество.
Но вот полностью функции писать в верстке. Сомнительное это преимущество.

Так я его в недостатки записал

Поэтому от мало-мальски сложного проекта на QtQuick начинают течь слезы, если только разработчик не заставил себя следовать какой-нибудь методологии

QML — это всего лишь GUI, и javascript там нужен для реализации логики GUI. Бизнес-логика должна реализовываться отдельно. Имо если в проекте много говнокода, слезы потекут независимо от того, на чем он написан

Тут на самом деле есть один тонкий момент — никто не запрещает написать так:


{
    "StackPanel": 
    {
        "TextBlock": "Hello world",
        "Button":
        {
            "Text": "Click me"
        }
    }
}

но тут встает вопрос с повторением свойств, например:


{
    "StackPanel": 
    {
        "TextBlock": "Hello world",
        "Button":
        {
            "Text": "Click me"
        },
        "Button":
        {
            "Text": "And me!"
        }
    }
}

Парсеры, тот же JSON.parse, при повторении свойства вернет значение именно последнего свойства (работает аналогично инициализации объекта), а вот при потоковом парсинге (например с помощью JsonTextReader из Json.NET) мы увидим все свойства, даже повторяющиеся и можем их корректно обработать. Но это очень холиварный момент. Очень.

Пока я из XML читал только XAML и ATOM мне всегда было не ясно, как JSON может быть более читаем: он менее строгий и ограничен единственной конструкцией Ключ-Значение, которой описывается и свойства и иерархия. Когда у xml свойства могут быть атрибутами, а иерархия это всегда вложенные теги.

Потом я уже столкнулся с plist. Когда xml используется по json-идеалогии. тогда его из-за излишней многословности читать действительно сложнее.

Воспользуюсь примером kekekeks:
Если сравнивать такой json:
{
  "@type": "StackPanel",
  "children": [
    {
      "@type": "TextBlock",
      "text": "Hello world"
    },
    {
      "@type": "Button",
      "text": "Click me"
    }
  ]
}

И XML написанный в том же стиле (примерно как plist):
<panel>
  <type>StackPanel</type>
  <children>
    <control>
      <type>TextBlock</type>
      <text>Hello world</text>
    </control>
    <control>
      <type>Button</type>
      <text>Click me</text>
    </control>
  </children>
</panel>

То, конечно, json выигрывает. Но нормальный XML намного удобнее:
<StackPanel>
  <TextBlock>Hello world</TextBlock>
  <Button Text="Click me"/>
</StackPanel>


Тут тег однозначно сопоставляется с экземпляром объекта, свойства объекта с атрибутами. Иерархия тоже легче читается.
По выразительности ни XML, ни JSON не сравнится с QML.
Напомнило демку с диска к книге Страуструпа за 99 год вроде. Там аналогичный эффект был, правда без паралакса и под DOS. Хороший был диск. А сколько там было исходников вирусни того времени — ух…
Ухты. А как Avalonia это делает? Dotnet core — он же GUI биндингов не имеет? Они что, через интроспекцию лезут напрямую в ось, в рантайме проверяют что за ось и в рантайме же биндятся к нужным GUI апишкам?

Там всё достаточно примитивно в плане детекта — RuntimePlatform.GetRuntimeInfo().OperatingSystem выдаёт текущую операционку. А дальше создаются окошки уже через P/Invoke либо к Win32 API, либо к GTK3, либо к Cocoa.


Подробнее по архитектуре см. с 15:00 здесь

Ага, то есть «P/Invoke». Неторопливая штука в целом. Не факт, что быстрее Electron.

Вы точно понимаете, как работает P/Invoke? Вы точно понимаете, как именно работает электрон и почему именно он тормозит?

Если .net хочет вызвать, к примеру, «SendMessageW» на винде, то она делает преобразования для всех аргументов (потому что строка в .net и null-terminated UCS-2 в WinAPI — это разные штуки), потом вызов, потом преобразование возвращаемых знаечений, если есть. Electron — это просто Chromium. В нем оптимизированный движок для рендеринга HTML, он компилирует JS в нативный код, все взаимодействие между скомпилированным JS и HTML бесшовно.

Но специально я не сравнивал — любопытствую. Демка из статьи выше у меня запустилась сильно медленнее, чем стартует Visual Studio Code. Да, воторой запуск такой же медленный, как первый :)
потому что строка в .net и null-terminated UCS-2 в WinAPI — это разные штуки

На самом деле нет, дотнетные строки нуль-терминированы, вы можете взять указатель и передать как есть. Да, в ряде случаев маршалинг нужен, но это контролируемый процесс. Так, всё взаимодействие с DirectX у нас идёт через msil-инструкцию calli, которая выполняет прямой вызов по указателю без автоматических преобразований.


Демка из статьи выше у меня запустилась сильно медленнее, чем стартует Visual Studio Code

А вы её запускали через dotnet run? Он каждый раз дёргает MSBuild и кучу ненужностей, чтобы определить, надо ли пересобрать проект (и обычно пересобирает даже тогда, когда не надо). Процесс этот не быстрый. Сделайте dotnet publish под нужную платформу и уже собранный релизный вариант запустите.

msil-инструкцию calli, которая выполняет прямой вызов по указателю без автоматических преобразований

Интересно, а где можно на это посмотреть?

См. SharpGenTools, которым обрабатывается используемый нами SharpDX в процессе сборки. Мы себя отдельно SharpGenTools используем в AvalonStudio для генерации кода интеропа с libdbgshim/ICorDebug для отладки кода под .NET Core.

"Неторопливая" — очень относительное понятие. Да, PInvoke медленный по сравнению с прямым вызовом функции, он добавляет от 10 до 30 инструкций (см MSDN). Но надо понимать, что эта разница — порядка наносекунд, и в случае вызова функций сложнее a+b просто теряется. Например, Ignite.NET работает с JVM через PInvoke, и тормозов от этого не испытывает.


Electron:


  • тащит за собой целый браузер, жрёт немеряно памяти и создаёт новый процесс на каждый чих
  • C# быстрее JavaScript и лучше во всех отношениях
  • XAML лучше HTML

Другое дело, что layout & rendering в Electron действительно может быть быстрее для некоторых сценариев, браузерный движок очень круто заоптимизирован под это дело.

layout & rendering в Electron действительно может быть быстрее

Так рендерилку (Skia) мы у них в цельнотянутом виде утащили. На не-windows-платформах используется.

Спасибо за статью и рекламу Avalonia! Очень нравится концепция, надеюсь выстрелит.

Классический эффект ранних интро.
Единственное — в этом эффекте у снежинок обычно добавляли небольшие флуктуации по горизонтали — как это и выглядит в натуре, если нет ветра.
Добавил эту фичу и сделал pull-request: https://github.com/ptupitsyn/let-it-snow/pull/1/commits

Я бы посмотрел ответочку от

  • Java
  • Kotlin
  • WebAssembly? O_o
UFO just landed and posted this here
Господа, а нормальный-то WPF не планируется к .net core что ли?

Нет. Вместо него поверх CoreCLR работает UWP. Который нигде кроме Windows 10 работать не планирует.

UFO just landed and posted this here

Где? В .NET Core? Или поддержка вайном UWP? Первое технически слабореализуемо (Mono уже пытались когда-то давно реализовать поддержку WinForms поверх вайна, получилось плохо), во второе слабо верится, ввиду общей непопулярности UWP как платформы.

UFO just landed and posted this here

Они его продвигать могут сколько угодно, но разработчиков под UWP от этого не прибавится. По фичам он проигрывает WPF всухую, а единственную платформу, ради которой это дело хоть кто-то использовал, благополучно похоронили.

UFO just landed and posted this here
Под win S запускаются только приложения рз маркета.

Через Desktop Bridge на этой Win S хоть Windows Forms можно запустить.

По фичам он проигрывает WPF всухую

Ну нет же (в смысле не всухую). Все новые фичи API делаются в WinRT и в WPF доступны только через костыли в виде Desctop Bridge.

Те фичи, что не поддерживаются в WinRT либо в планах, либо под вопросом существования (как например трей).

Grid.SharedSizeGroup завезли уже? А свои MarkupExtension уже можно делать? Уже сколько лет технологии, а даже таких базовых вещей нет.


А WinRT-only-фичи — это какое-нибудь живое обновление плиток, которое нужно мессенджерам и приложениям по доставке пиццы.

Вы хотите передергивать, или объективности?
Если передергивать, то кому нужны все эти Grid.SharedSizeGroup и MarkupExtension?

В WPF завезли нормальную поддержку DPI и UI Адаптивный под разные инструменты ввода? Даже таких базовых вещей нет.

А WinRT-only-фичи, кроме вами озвученных — пуш уведомления, поддержка экстеншенов из коробки, нормальная поддержка HDPI, SvgImageSource, Composition API, поддержка windows timeline из коробки, пакетная упаковка приложений (аля мак ос).
кому нужны все эти Grid.SharedSizeGroup и MarkupExtension

Нужны при разработке чего-то более сложного, чем приложение для доставки пиццы. Свои markup extensions даже в Xamarin.Forms есть.


В WPF завезли нормальную поддержку DPI и UI Адаптивный под разные инструменты ввода

DPI всегда вполне вменяемо поддерживался. В 4.6.2 прикрутили поддержку per-monitor DPI. С DPI проблемы были не в WPF, а в винформах, ибо винформы базируются на технологиях из 90-х


пуш уведомления
пакетная упаковка приложений (аля мак ос).

Делается через desktop bridge, к технологии отображения окон на экран отношения не имеет.

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

Ок, продолжу ваше ребячество:
Ничего сложнее «приложения по доставке пиццы» нельзя написать не используя RelativePanel, AdaptiveTrigger и условного XAML (последний «даже в Xamarin.Forms есть» в каком-то виде).

В 4.6.2 прикрутили поддержку per-monitor DPI.
Ага бекпортировали из UWP в технологии 00-х.

Делается через desktop bridge

Как я выше и писал, через костыли в виде Desktop to UWP Bridge. Тогда только Классическим (аккуратное слово, означающее то же, что и легаси в общем-то) приложениям разрешают доступ до современного WinRT API.

AdaptiveTrigger реализуется средствами WPF посредством биндинга к ActualWidth и конвертера. RelativePanel при желании можно реализовать самостоятельно, более-менее работающая есть на гитхабе.
Условный XAML делается на уровне своего markup extension (как это сделано в Xamarin.Forms)

А SharedGridSize это такая незаменимая сверхмагия разработанная надмозгом?
Ну и услвный XAML в XF выглядит так:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:ios="clr-namespace:UIKit;assembly=Xamarin.iOS;targetPlatform=iOS"
        xmlns:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
        xmlns:formsAndroid="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.Platform.Android;targetPlatform=Android"
        xmlns:win="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows, Version=255.255.255.255,
            Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime;targetPlatform=Windows"
        x:Class="NativeViews.NativeViewDemo">
    <StackLayout Margin="20">
        <ios:UILabel Text="Hello World" TextColor="{x:Static ios:UIColor.Red}" View.HorizontalOptions="Start" />
        <androidWidget:TextView Text="Hello World" x:Arguments="{x:Static formsandroid:Forms.Context}" />
        <win:TextBlock Text="Hello World" />
    </StackLayout>
</ContentPage>

А расскажите что мешает например сделать биндинги к Qt(зачем ещё одна графическая либа)? Известный фреймворк, сделан профессионально, из коробки до кучи фич от лайв редактирования до трансляции в браузер. Кастомизируется по самое нехочу. Отличная лицензия. Из недостатков только что веб в один клик не запилить(хотя зная современный веб это можно считать плюсом) и что заставляет под себя подстраиваться (хотелось бы более универсальное как стандартная библиотеки, чтобы не тянуть зависимости ядра, а сразу заюзал функционал в любой проект без остального qt).

Дата-биндингов нормальных нет, шаблонов нормальных нет, lookless-контролов нет, т. е. идеологически Qt застрял где-то во временах Windows Forms и Delphi 7. А так хороший фреймворк, никто не спорит.

Здорово! Приятно видеть, что UI dotNet с XAML можно запускать на этих платформах.

Sign up to leave a comment.

Articles