Изучая первый язык я хотел видеть кнопочки, а не только текст в консоли. Я сделал на Python3+tkinter калькулятор. Это заняло 585 строк. Применив к коду магию py2app, я получил bundle размером 45MB. Мне не понравилась работать с py2app. Иногда все переставало работать, если использовались сторонние библиотеки, а иногда я исправлял код py2app. Из-за этого я думал, что standalone-приложения делать очень сложно.
Через год я познакомился с xCode и калькулятор для iOS занял всего 125 строк. Нужно учитывать, что кнопки были сделаны в визуальном редакторе, а из операций я оставил только: «+», «-», «*», «/». Bundle получился меньше 10 MB.
Пару недель назад я нашел способ сделать калькулятор для Mac OS без xCode. У меня получилось уложиться в 57 строк и я перестал бояться Swift.
import AppKit
let winWid: CGFloat = 256
let wihHei: CGFloat = 180
let dispHei: CGFloat = 18
let rows = 4
let rowHei: CGFloat = 32
class AppDelegate: NSObject, NSApplicationDelegate {
lazy var window = NSWindow(contentRect: NSMakeRect(0, 0, winWid, wihHei),
styleMask: [.titled, .closable], backing: .buffered,
defer: false, screen: nil)
let display = NSText(frame: NSMakeRect(0, wihHei - dispHei, winWid, dispHei))
func applicationDidFinishLaunching(_ notification: Notification) {
window.title = "Machine"
window.contentView?.addSubview(display)
let eq = NSButton(frame: NSMakeRect(0, 0, winWid, rowHei))
eq.title = "="
eq.target = self
eq.action = #selector(eval)
window.contentView?.addSubview(eq)
let items = ["C","0",".","/","1","2","3","*",
"4","5","6","-","7","8","9","+"]
let sz = CGSize(width: (winWid/CGFloat(rows)),
height: rowHei)
for i in 0..<items.count {
let x = i % rows
let y = i / rows
let b = NSButton(
frame: NSMakeRect(sz.width * CGFloat(x),
sz.height * CGFloat(y) + rowHei,
sz.width, sz.height))
b.title = items[y*rows+x]
b.target = self
b.action = i==0 ? #selector(clear) : #selector(input)
window.contentView?.addSubview(b)
}
window.makeKeyAndOrderFront(nil)
}
@objc func input(sender: NSButton) {display.string! += sender.title}
@objc func eval(sender: NSButton) {
let exp: NSExpression = NSExpression(format: display.string!)
if let result: Double = exp.expressionValue(with: nil, context: nil) as? Double {
display.string = String(result)
}
}
@objc func clear(sender: NSButton) {display.string = ""}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
let delegate = AppDelegate()
var appl: NSApplication
#if swift(>=5.1)
appl = NSApplication.shared
#else
appl = NSApplication.shared()
#endif
appl.setActivationPolicy(.regular)
appl.delegate = delegate
appl.run()
Если сохранить код в main.swift и запустить в терминале команду:
swiftc main.swift
Мы получим бинарный файл, который можно упаковать в приложение или просто запустить в терминале. Калькулятор считает не совсем привычным образом. Кнопка "=" вычисляет все, что написано на дисплее.
Но больше всего, меня обрадовал язык Red. Калькулятор на нем можно поместить в 13 строчек. А размер standalone приложения для MacOS будет всего 1 MB.
Red [Needs: View]
View [
title "Red"
disp: field 330x50 font-size 25 "" return
style b: button 71x40 [append disp/text face/text]
b "1" b "2" b "3" b " + " return
b "4" b "5" b "6" b " - " return
b "7" b "8" b "9" b " * " return
b "0" b "." b " / " b " = " [attempt [
result: form do disp/text
append clear disp/text result]] return
button "C" 325x40 [clear disp/text]
]
Сохраняем код в main.red и набираем в консоли:
red -t macOS main.red
На сайте объявлено, что приложения можно собирать под Windows, Linux, MacOS и др платформы.
Жаль, что разработчики языка пока не среагировали на то, что Apple не поддерживает 32-битные приложения после версии macOS 10.15
Буду рад, если кто-нибудь подскажет более простые варианты создания GUI.
Автор: Alexander Veledzimovich