Комментарии 160
А вот здесь пример калькулятора.
Два интересующих файла — Calculator.kv и main.py.
Буду рад, если кто-нибудь подскажет более простые варианты создания GUI.
Пишем веб-интерфейс, а затем встраиваемый его в любое приложение на любой платформе на любом языке. Например, электрон, cef, Cordova.
… и получаем калькулятор, тянущий за собой chromium и node.js и отжирающий чуть менее чем полгига RAM на ровном месте. Это из категории "вредные советы"?
Возможно, вам стоит рассказать разработчикам из Microsoft про профайлер и все такое, а то они не знают, наверное.
Вы же страдаете, а не я. Никогда не задумывались, почему одно приложение потребляет 30 мб, а его аналог в 10 раз больше? Это как бы намекает на скрытые функции…
впрочем, Process Explorer может доказать что я неправ
Впрочем, 60 мб — всё-равно приемлемое число.
Для калькулятора?
Но, с другой стороны, тот же дискорд, что вы упоминаете ниже, работает отлично и хороших кроссплатформенных аналогов фактически не имеет. И в 2019 жаловаться на обьем оперативной памяти это моветон. Этим летом я купил 64Gb оперативной памяти с частотой 3200 всего лишь за жалкие 200$.
Очень надоело это нытье из разряда «раньше было лучше, на моем нетбуке с xp-шечкой все шустро запускалось, и бравзер и ворд и винумп и даже видосики 720p!!!.. А вот сейчас веб макаки все испортили и моих ЦЕЛЫХ!!! 512mb уже не хватает!!!»
И оказывается что никому не интересно в текущих реалиях жрет приложение 300 или 500mb. Зато интересно другое, в случае того же слака или скайпа, и в ситуации когда девайса под рукой нет, есть гостевой комп и срочно нужно что-то порешать аж за океаном.
И последний момент. Не нравится — не пользуйся. Очень доставляет категория людей считающая что им все должны.
Мне — интересно. Поэтому дискордом я не пользуюсь вовсе, а скайпом — только при очень большой необходимости, и то потому, что пара моих контактов другого способа оперативной связи не имеет. Рано или поздно откажусь и от него, так как считаю, что писателей откровенно плохо написанного софта поощрять не стоит. Эти "веб-макаки", как вы выражаетесь, в случае Скайпа даже не смогли толком воспроизвести уже имевшийся функционал из Скайп Классик, зато раздули потребление ресурсов сверх всякой меры. Это не тот путь, которым следует идти.
Грубо говоря всем управляют «бабки», то есть запросы по функционалу неплатежеспособных (это даже не зависит от ваших реальных финансовых возможностей, а лишь от готовности тратить деньги) пользователей просто игнорируются. А платежеспособная часть просто может себе позволить более мощное железо. Именно по этой причине выпускают игры под новые консоли, а не под старые.
В целом я за сбалансированный подход. Специализированный и сложный софт должен быть нативным, быстрым и потреблять минимум ресурсов.
Остальной софт — выбор за пользователями и разработчиками. Если большинству выгоднее chromium — то почему нет?
"Более мощное железо" потихоньку тоже перестаёт решать, производительность уже давно не удваивается каждые 18 месяцев. Скайп теряет рынок:
не в последнюю очередь из-за применения сомнительных технических решений, которые удобны для разработчиков, но не для пользователей.
Скайп в основном же сожрали whatsapp, slack, viber и телеграмм. Так же сдох когда-то ICQ. Кстати ICQ работало даже на железе уровня микроволновки, но его это не спасло.
Кроме того компания, где я работаю, долго использовала Skype, но затем тоже перешла на Slack.
Да, но почему они его сожрали? Не потому ли, что MS тупо перестал прислушиваться к желаниям пользователей, а вместо этого начал ваять жручий, тормозной и малофункциональный мусор?
Насколько я знаю (могу ошибаться) Skype до сих пор очень популярен в латинской америке. Вот немного статистики по нему.
Кстати кому интересно есть проект node + qt5 — тоже кроссплатформа, тоже Javascript, но без chromium.
Лично я считаю, что тот же QML сделан гораздо более пригодным для standalone приложений, чем html/css, которые изначально вообще для приложений как таковых не предназначались. Раджеши Кутрапале, конечно, наваяют вам ЧТО-ТО… Но как бы потом с этим "что-то" не получилось, как у MS со Скайпом. ИМХО использование вещей типа Электрона допускается только как временное решение — если нужно быстро сделать приложение на базе уже имеющегося веб-решения, это их ниша. Застолбить преимущество. Но затем с этого нужно уходить, а то юзеры проклянут, и уйдут к более оптимизированным конкурентам, а такие обязательно появятся.
Лично я предпочитаю Qt. Я из тех самых "бородатых разработчиков", правда, бороды у меня все-таки нет :) Но тут есть нюанс — Qt — это все-таки для вещей посложнее калькулятора. Вот для таких, например:
https://www.inobitec.ru/products/dicomviewer/
Для калькулятора Qt все-таки жирноват.
Предупреждать же надо! Приложение, может, и хорошее, но я ослеп на первой же странице сайта. Белый текст на светло-голубых макаронах… я слишком стар для этого...
С QtWebEngine — то неудивительно.
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Calculator")
ColumnLayout {
anchors.fill: parent
spacing: 16
TextField {
id: textField
readOnly: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
}
GridLayout {
rows: 4
columns: 4
Layout.fillWidth: true
Layout.fillHeight: true
Repeater {
model: ["7", "8", "9", "+", "4", "5", "6", "-", "1", "2", "3", "*", "C", "0", "=", "/"]
Button {
text: modelData
Layout.fillWidth: true
Layout.fillHeight: true
onClicked: {
if (text === "C") {
textField.text = "";
} else if (text === "=") {
try {
textField.text = evaluate(textField.text);
} catch (e) {
textField.text = e.message;
}
} else {
textField.text = textField.text + text;
}
}
function evaluate(expression) {
return eval(expression);
}
}
}
}
}
}
у меня кушает под виндой ~35Mb RAM, при этом просто пустой Window кушает столько же. Но, согласен, для куркулятора это тоже немало (к слову, штатный виндовый куркулятор кушает ~20Mb), поэтому я и написал выше про «жирноват». Но все же не 80-90. EXE занимает 28 килобайт, но не будем забывать про набор Qt'шных dll'ек, которые смело добавят еще метров 15 минимум. Хотя можно попробовать собрать статически, но возиться неохота — у меня Qt собран только в динамическом варианте.
Вместе с Qt я получаю QML и все необходимые библиотеки и если на MacOS собираю приложение, то оно работает для MacOS. Можно ли собрать приложение на MacOS для Windows/Linux?
Кстати, у меня тут возник вопрос. Допустим, я делаю приложение под Linux и хочу распространять еще и бинари, чтобы упростить людям жизнь. Не получится ли так, что мне придется делать версию под каждую поддерживаемую версию каждого поддерживамаего дистрибутива, ведь там могут отличаться версии Qt и вся бинарная совместимость накроется?
«раньше было лучше, на моем нетбуке с xp-шечкой все шустро запускалось, и бравзер и ворд и винумп и даже видосики 720p!!!
Ну да, и я должен пойти на поводу у веб-макак и выкинуть свой верой и правдой служащий мне >10 лет ThinkPad T60 потому что какому-то придурку лень запускать профайлер и оптимизировать софт.
Нуачо, ведь у абсолютно всех пользователей 64 гига оперативки. А тех, у кого 64 гигов нет — нужно спустить с парахода прогресса в биореактор, чтобы они не мешались.
Правильно объясняю? :)
P.S. На мне злость за это сгонять не надо. Это не я пишу глючный софт на электроне чтобы он у вас не запускался. А то вон понакидали минусов, словно я автор всех приложений на электроне.
Python — мир клея между библиотеками.
Вы предпочитаете не пользоваться библиотеками? Или суперобъёмная std вас смущает? На вашем языке библиотеки не принято использовать?
Алгоритмы ML не пишут на питоне
Я вас удивлю, но пишут.
бекенд, то рано или поздно либо умирают
Это проблема архитектуры и IDE, а не языке. Посмотрите PyCharm.
Нельзя к языку адекватно прикрутить типизацию сбоку, если он был создан без расчёта типизации.
Можно. Тем более, она в нём присутствует. Но даже если было бы нельзя, вам не хватило бы статического анализатора? Сдаётся мне, что какой-нибудь метод, который возвращает либо int, либо str, либо их кортежи, либо None, либо исключение — не есть проблема типизации.
new public List<[CanBeNull] Dict<int,(byte[],Hasher)>> GetNamedHashesByID<in Hasher>(ref [NotNull] CryptoContainer seed, params int[] ids) where Hasher:ICryptoHashAlgoritm {...}
GetNamedHashesByID(CryptoContainer seed, int[] ids)
чем так:
GetNamedHashesByID(seed, ids)
И гадать/всегда смотреть в доках, какого же типа аргументы.
Проблема типизации в том, что вы про это не знаете и знать не можете.
GetNamedHashesByID(null, null);
GetNamedHashesByID(null, new int[0]);
Теперь вам придётся гадать/всегда смотреть в доках, правильные ли значения аргументов были переданы. Получается, что вы типы добавили, а проблему не решили.
Ну и почему я должен половину работы сбрасывать языку, а вторую половину брать на себя? Тогда уж пусть язык сам все необходимые проверки делает и не выбрасывает исключения в рантайме или вообще не вмешивается. А если уж и вмешивается, то я сам хочу настроить, где и как.
Почему?
Потому что они правильные для компилятора, но неправильные для функции. Если функция рассчитывает на непустой массив, а на вход дали «правильный», но пустой, то в рантайме вылезет исключение, не смотря на все статические проверки.
У вас там NotNull было на первом параметре?
chersanya по каким-то причинам предлагает выкинуть половину сигнатуры.
Не надо в рантайме.
Согласен, я так и написал.
chersanya,
Про пример с null не понял, какое именно утверждение вы им иллюстрируете.
Nullable тип является указателем на этот тип, поэтому может оказаться «просроченным».
чтобы избавиться от этой «половины» работы/багов/тестов.
Всё-равно ведь придётся писать вторую половину. От 10 лишних строчек я не умру, а вот читать и учить мануалы про внутреннее устройство языка, чтобы опустить проверку на null… Это намного больше усилий потребует, чем написать
seed = seed || new DefaultSeed();
Только ведь всё равно получается лучше, чем в питоне.
1,228,588 репозиториев на гитхабе говорят об обратном (у С/С++ 549,210 репозиториев).
Nullable. Не понял. что значит «просроченным»
Это значит, что тип может иметь значение null. Такое значение нельзя привести к типу. Null — это отдельный тип. Поэтому, когда вы указываете nullable параметр в функции, вам надо это учесть. Компилятор не будет ругаться, даже если вы передали null вместо нормального значения. В итоге, в рантайме вылезет ошибка вида «Null reference exception».
Только она может оказаться сильно меньше.
А может и нет.
а 10 строк приходится писать постоянно.
Откройте для себя повторное использование кода.
Только вот, увы, все проблемы от nullability это не покрывает.
Какие?
В итоге, из обсуждения питоновских библиотек, алгоритмов и типов мы пришли к обсуждению null. Если вам нравится язык с 60% проверок, не надо говорить о бездарности языка с 40%, т.к. всегда найдётся 61% язык, который заявит о бездарности вашего.
1,228,588 репозиториев на гитхабе говорят об обратном (у С/С++ 549,210 репозиториев).
Если вы качество инструмента оцениваете по его популярности то лучше всех JS и PHP.
Только популярность с качеством не особо то коррелирует обычно.
Кажется, мы обсуждаем количество информации, передаваемой при чтении кода, а не количество репозиториев.
Я это не обсуждал. Возможно, вы меня перепутали с другим юзером.
У типа есть значение, которое нельзя привести к этому типу?
Например, создадим класс. Затем вызываем метод Hi.
public class A {
public void Hi()
{
Console.WriteLine("Hi!");
}
}
A x = new A();
x.hi(); //>>Hi
Теперь присвоим переменной null. И повторим.
x=null;
x.hi(); //ошибка рантайма
x = new null(); //ошибка компиляции
Удивительно, но значение есть, а метода нет. Почему? Потому что null нельзя привести к A (у него нет смещения на метод Hi).
Как вы повторно используете тесты, проверки на входящие типы и прочие подобные вещи?
1. копипаст
2. макросы
3. библиотеки аннотаций, декораторов, атрибутов, других обёрток
3. ide
4. расширение компилятора, анализатора, языка
5. чистые функции
6. шаблонизаторы, генераторы и фреймворки
chersanya по каким-то причинам предлагает выкинуть половину сигнатуры.
Да, предлагаю, и при этом одновременно предлагаю брать язык, где null по-умолчанию не разрешён. Среди популярных языков выбор таковых имеется.
Потому что они правильные для компилятора, но неправильные для функции. Если функция рассчитывает на непустой массив, а на вход дали «правильный», но пустой, то в рантайме вылезет исключение, не смотря на все статические проверки.
Разумеется нельзя все требуемые свойства входных параметров в общем случае вывести в тип аргумента. Например, если функция принимает на вход имя существующего файла.
Но чем больше ошибок отлавливается автоматически языком без запуска программы, тем лучше и надёжнее.
Nullable тип является указателем на этот тип, поэтому может оказаться «просроченным».
Как уже правильно написали, «nullable-ность» типа и то, является ли он указателем, вещи не связанные. Вообще в прикладном программировании задумываться об указателях особо не приходится. И что значит «просроченным»?
Ну и почему я должен половину работы сбрасывать языку, а вторую половину брать на себя?
По-моему ответ очевиден, разве нет? Чтобы избавиться от этой «половины» работы/багов/тестов.
Мне нравилось, что у lua динамическая типизация. Удобно для маленьких проектов и скриптов. Но я не изменять тип переменной и обращался с языком, как со статическим. Параметров в функциях не хватает.
GScript (язык движка Godot) позволяет указать явно тип, но пока не делает это правило обязательным.
После, близкого знакомства со swift, понял, что статическая типизация мне больше нравится, чем нет. Это просто удобно.
public type1, type2, type3 x = new type1();
), и универсальный тип, и неявное автоприведение типов. А если вспомнить про супертипы, то открывается прекрасный дивный мир динамической типизации. Так ещё и системы вывода типов научились это дело проверять прямо в IDE. А было бы лучше
Ну да. Это получается динамическая типизация второго порядка. А ещё IDE умеют автоматически разбивать динамически типизированные переменные на статически и размечать типы, когда достаточно написать пример использования.
Так как его сформулировать-то?
Так разве не вы написали? Привязка типов в райнтайме — динамическая, в компиляторе — статическая, причём 1 к 1.
Компилятор вас всего лишь заставляет писать с учётом возможной нулябельности. Где ж тут динамическая типизация?
В рантайме тип может поменяться на null.
public type1, type2, type3 x = new type1();
Переменная x может иметь либо тип1, либо тип2, либо тип3.
Касты проверяются статически
А выполняются в рантайме => динамическая.
Нет, апкасты всё равно происходят во время компиляции.
Только если типы можно вывести. Поэтому тоже динамическая.
И чем это отличается от гарантированного вывода типов
Большая гибкость, больше возможностей, меньше запретов, больше свободы.
А можно пример апкаста, когда типы вывести нельзя?
class C:A,B {...}
Множественное наследование, например. Куда будет приведён класс C? Непонятно, зависит от ситуации.
Если я на С стану писать, оперируя лишь структурами вида с ручными проверками typeTag перед каждой операцией, то динамически типизированным он от этого не станет.
Конечно, у вас типы уже привязаны заранее, а оперируете вы их значениями.
Т.е. вы видите, что rust удобнее для вас чем известный вам с++?
Да, только на C++ у вас весь код ансейф, а на расте он явно выделен соответствующим образом.
Убер-аргумент, сдаюсь! :) Закрыли паллетами, значит, все хорошо. Да это я так, троллю, понятно, что все это уже по сто раз обсуждалось.
И не могу сказать про раст, но на том же хаскеле ансейф-код мне приходится писать примерно никогда. Даже FFI норм получается.
Вы просто выносите unsafe код в C/C++ либы, ну а к ним уже FFI :)))
А размер standalone приложения для MacOS будет всего 1 MB.
Грустно конечно, что для простейшего калькулятора миллион байт — это «всего».
Посмотрел среди старых исходников написанный интереса ради калькулятор — 360 кб.
Куда мы идем хз.
Вы о какой трудоемкости вообще говорите? Кнопочек на форму накидал, процедур навешал и готово.
зы можно было и под другие платформы компилить.
Но если под другую платфоому, то там должны быть библиотеки WinAPI, так? И тогда уже не 10 кб, а больше.
Т.е. вы можете при сборке указать MacOS целевой платформой и получить бинарный файл готовый к использованию и без зависимостей?
Вот я ищу максимально простое решение. Нечто, что может делать приложения для всех платформ из коробки, как игровые движки.
Понятно, что калькуляторы без ОС запускать — глупость, но это просто как иллюстрация возможностей.
Ну, можно собрать из исходников FORTH под bare metal.
Он сам по себе и язык программирования, и операционка, и калькулятор :)
И я считаю, что это очень много. По сравнению с JPEG Stripper'ом на 25600 байт. Или bred'ом на 183296 байт.
На сегодняшний день, какая есть альтернатива? Кроме electron. Не обязательно с визуальным интерфейсом.
Электрон тут «нужен» разве что чтобы от браузера «отказаться», только это только видимость будет.
А вот так, чтобы на выходе был бинарник… тут я вам не подскажу. Особенно если хочется бинарник кроссплатформенный.
Со статической будет в разы тяжелее
впрочем мог и 7 скомпилить давно было не помню
Хорошо, а в чем тогда подвох? Почему эта технология постепенно исчезает?
Дизайн виджетов устарел?
Можно ли на windows собрать программу для запуска в macOS, чтобы на macOS не устанавливать зависимости?
Например, вы перешлете мне файл на 12 кб и я смогу запустить калькулятор?
delphi практически вытеснили с рынка
настолько что их купила другая компания
сейчас разработкой занимается не borland а embarkadero
сломали интерфейс стремясь быть похожими на vs что оттолкнуло кучу разработчиков от новых версий.
а потом и совместимость со старым кодом частично сломали ради улучшения кросплатформенности
да, теперь кроме windows linux и macos можно компилировать и под ios с android
но это требует переписывания кода и использования значительно более тормознутой системы gui.
в общем на данный момент rad система практически мертва изза неправильного развития хоть разработчик и пытается увеличить популярность.
lazarus живее (за счет бесплатности) но куда менее оптимизирован
зы под линукс собрать точно можно было а вот под макось не пробовал
там куча лицензионных заморочек чтоб эпплу в аду икалось
Спасибо за ответ, теперь стало понятнее. Я пока работаю с MacOS.
И пока из всех ответов я не нахожу решения проще чем предлагают разработчики языка Red.
Устанавливаешь один файл, в нем все что нужно для работы и компиляции GUI приложения для разных платформ.
Язык в версии 0.64, если доведут до конца, будет любопытная штука.
Кстати, в нем сильно чувствуется наследие Scheme.
Спасибо.
Сегодня, пока общался на хабре открыл очень удобную библиотеку Python для визуализации данных streamlit
Извините, что без ссылки.
По принципу работы чем-то похоже на imgui и nuklear
Читаю обзор flow9 на сайте. Классная штука, завтра буду пробовать.
Если окажется, проще чем Dart, то непонятно, почему малоизвестна.
За правильность логики самого калькулятора не ручаюсь, делалось на скорую руку. Но построение интерфейса видно. Количество строк можно сократить, но читать код будет труднее. Ну и сам внешний вид можно менять если взять ttk
wm title . "Tcl/TK calc"
pack [frame .frm] -expand true -fill both
grid columnconfigure .frm 0 -weight 1
grid rowconfigure .frm 0 -weight 1
entry .frm.ent
grid .frm.ent -row 0 -columnspan 5 -sticky nswe -padx 5 -pady 5
proc Calculate {ent txt} {
if [regexp -nocase -all -- {([0-9]+)(\+|\*|\/|-)([0-9]+)} $txt match v1 v2 v3] {
$ent delete 0 end
$ent insert end [expr double($v1) $v2 double($v3)]
}
}
set col 0
set row 1
foreach item {1 2 3 4 5 6 7 8 9 0 + - * /} {
button .frm.btn_$item -text "$item" -command [list .frm.ent insert end $item]
grid .frm.btn_$item -row $row -column $col -sticky nswe -padx 5 -pady 5
incr col
if {[expr fmod($col, 5)] eq "0.0"} {
incr row
set col 0
}
}
button .frm.btn_calc -text "=" -command {
Calculate .frm.ent [.frm.ent get]
}
grid .frm.btn_calc -row 3 -column 4 -sticky nsw -padx 5 -pady 5
Хорошо, а что нужно, чтобы получить бинарный файл для MacOS?
Или просто достаточно установленных библиотек tcl/tk?
import calc
calc()
Две строчки. Я победил.
1262 байт. Сохранить в файл с именем calc.hta (работает только под win)
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="ie=9">
<title>calc</title>
<HTA:APPLICATION border="dialog" maximizeButton="no" icon="calc.exe" applicationName="calc" innerBorder="no" navigable="no" scroll="no" />
<style>
* {
font-family: monospace;
}
</style>
</head>
<body>
<input type="text" id="c" /><br>
<script>
window.resizeTo(200,200)
var c = document.getElementById('c');
[
7, 8, 9, '-', 0,
4, 5, 6, '/', 0,
1, 2, 3, '*', 0,
'0', '.', '+', '='
].map(function (e) {
if (!e) {
document.body.appendChild(document.createElement('br'));
} else {
var i = document.createElement('input');
i.value = e;
i.type = "button";
document.body.appendChild(i);
i.addEventListener('click', function () {
if (e == '=') {
try { c.value = eval(c.value); } catch (e) { }
} else {
c.value += e;
}
});
}
});
</script>
</body>
</html>
Моих знаний JS, для такой штуки достаточно. Спасибо. Этой штуке не нужен браузер?
Кроме стандартных браузерных js функций доступен системный api
Пример чтения локального файла
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TEST</title>
</head>
<body>
<div id="content"></div>
<script language="VBScript">
Function loadLocalFile(fileName)
set oFSO = CreateObject("Scripting.FileSystemObject")
set oFile = oFSO.OpenTextFile(fileName, 1)
text = oFile.ReadAll
oFile.Close
loadLocalFile = text
End Function
</script>
<script type="text/javascript">
document.getElementById('content').innerText = loadLocalFile('lorem.txt');
</script>
</body>
</html>
1. Простая установка на любую платформу (скачиваем установщик или собираем c помощью make или cmake имея только gcc или clang)
2. Возможность собрать приложение для работы на разных платформах. Компиляция или другие способы. Без проблем и дополнительных инструментов. Желательно одна или две команды в терминале.
3. Приложение на выходе меньше 50 мб
Если у человека основная область деятельности далека от разработки ПО, то C++ ему все-таки в руки лучше не давать. Пусть уж прототипирует на том же Питоне то, что ему надо, а вот если это нужно будет потом запустить в продакшн под нагрузочкой, то тут уже можно и на C++ это перевести с помощью специально обученных людей. Тем более для Питона существуют официальные Qt-биндинги:
https://www.qt.io/qt-for-python
https://doc.qt.io/qtforpython/tutorials/qmlapp/qmlapplication.html
Более 100 демо-программ
Поиски «идеального» GUI. Путь новичка