Если вы пишете на Go и вам нужен нативный GUI, выбор невелик. Есть
fyne, есть gio, есть веб-обёртки. Но если нужен полноценный Qt с виджетами, диалогами, таблицами и всей экосистемой — до недавнего времени единственным рабочим вариантом был therecipe/qt. У него LGPL-лицензия, нет поддержки Go-модулей, нет Qt 6, и архитектура через IPC с отдельным C++-бинарником.MIQT — это прямые биндинги Qt 5.15 и Qt 6.4+ через CGO, под лицензией MIT. Никаких промежуточных процессов, никаких рантайм-зависимостей от авторских серверов. Вы вызываете Qt напрямую из Go-кода.
Что внутри
Биндинги покрывают QtCore, QtGui, QtWidgets, QtMultimedia, QtNetwork, QtWebEngine, QtCharts, QML, и ещё десяток модулей. Есть поддержка subclassing (можно переопределять виртуальные методы вроде
PaintEvent), собственная реализация uic и rcc для работы с Qt Designer, и инструмент miqt-docker для кросс-компиляции.Проект стартовал в августе 2024, но уже набрал 600+ звёзд и оброс реальными приложениями: менеджер Docker-контейнеров, просмотрщик JSON, загрузчик видео, RTSP-клиент для камер.
Как выглядит код
API максимально приближен к оригинальному Qt C++. Контейнерные типы Qt (
QString, QList, QMap) проецируются в нативные Go-типы: string, []T, map[K]V. Сигналы и слоты работают через коллбэки:button := qt.NewQPushButton2("Нажми меня")
button.OnClicked(func() {
qt.QMessageBox_Information(
window,
"Привет",
"Это MIQT",
)
})Наследование классов Qt реализовано через встраивание структур. Чтобы передать
*qt.QLabel в функцию, принимающую *qt.QWidget, пишете myLabel.QWidget.Платформы
MIQT работает на Linux (x86_64, ARM64), Windows (x86_64), macOS (x86_64, ARM64), FreeBSD и Android. Поддерживается и статическая, и динамическая линковка. Для Windows и Android есть готовые Docker-образы для кросс-компиляции.
Нюансы, о которых стоит знать
Первая сборка занимает около 10 минут. Все последующие быстрые, потому что CGO-часть кешируется. На Go 1.26 стало ещё быстрее.
Бинарник по умолчанию получается большим. С флагами
-ldflags "-s -w" helloworld уменьшается с 43MB до 6MB. С upx --best — до 2MB.Сравнение указателей на Qt-объекты в Go работает не так, как в C++.
QTabWidget.CurrentWidget() каждый раз создаёт новую Go-структуру, оборачивающую тот же C++-указатель. Для сравнения используйте .UnsafePointer() или сравнивайте по индексу.Горутины мигрируют между OS-потоками, а Qt привязывает объекты к конкретному потоку. MIQT автоматически вызывает
runtime.LockOSThread() при создании QApplication. Для доступа к Qt-объектам из других горутин используйте mainthread.Wait() или mainthread.Start().Быстрый старт на Linux
Ставим зависимости, пример для Debian/Ubuntu с Qt 6:
apt install qt6-base-dev build-essential golang-go
Собираем:
go build -ldflags '-s -w'
Для кросс-компиляции под Windows:
go install github.com/mappu/miqt/cmd/miqt-docker@latest
miqt-docker win64-qt6-static -windows-build --tags=windowsqtstatic
MIQT — это способ писать Qt-приложения на Go без лицензионных ограничений LGPL. Биндинги зрелые, покрытие API широкое, кросс-платформенность работает. Если вам нужен нативный десктопный GUI на Go с полным набором виджетов, MIQT сейчас самый практичный вариант.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoToProduction