Abnormal programming
Programming
.NET
C#
Development for Linux
Comments 55
-1
PyQt это опять же — Qt. Лично по мне так он довольно сложен для понимания, особенно QML. Все-таки самый лучший способ писать интерфейс разметкой — это xml (и его расширения типа XAML и т.д.). А вот в json разметку еще и намешанную с js воспринимать очень тяжело.
+10

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

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

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


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

вместо


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

В QML это будет


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

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

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

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


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

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

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

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

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

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

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

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

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

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


{
    "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) мы увидим все свойства, даже повторяющиеся и можем их корректно обработать. Но это очень холиварный момент. Очень.

+7
Пока я из 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>


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

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


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

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

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

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

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

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


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

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

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

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

+3

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

+6

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


Electron:


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

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

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

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

+7

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

+2

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

UFO landed and left these words here
+1

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

UFO landed and left these words here
0

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

UFO landed and left these words here
0

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

UFO landed and left these words here
0
По фичам он проигрывает WPF всухую

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

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

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


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

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

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

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

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


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

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


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

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

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

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

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

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

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

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

0
А SharedGridSize это такая незаменимая сверхмагия разработанная надмозгом?
0
Ну и услвный 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>
0

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

+5

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

+2

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

Only those users with full accounts are able to leave comments. , please.