小编整理了有关golang开发windows桌面的知识,希望对你有所帮助:
在 awesome-go 节点下有不少开发界面的库, 大部分是基于web, gtk, qt跨平台的, 也有基于sciter go绑定的go-sciter, 基于原生包装的跨平台的库ui, 只支持Windows桌面端的walk
个人倾向于后2个, 适合个人的技术栈, 试用了下ui这个库, demo比较 少就4个, 运行起来有点卡, 而且生成的可执行文件很大. 最重要的是不支持设置控件坐标(没找到), 而且开放的接口比较少.
下面对比下ui和walk代码, 就拿button控件来说. - ui
- walk
- type Button struct {
- WidgetBase
- checkedChangedPublisher EventPublisher
- clickedPublisher EventPublisher
- textChangedPublisher EventPublisher
- imageChangedPublisher EventPublisher
- image Image
- persistent bool
- }
- type WidgetBase struct {
- WindowBase
- parent Container
- toolTipTextProperty Property
- toolTipTextChangedPublisher EventPublisher
- graphicsEffects *WidgetGraphicsEffectList
- alwaysConsumeSpace bool
- }
- type WindowBase struct {
- window Window
- hWnd win.HWND
- origWndProcPtr uintptr
- name string
- font *Font
- contextMenu *Menu
- disposables []Disposable
- disposingPublisher EventPublisher
- dropFilesPublisher DropFilesEventPublisher
- keyDownPublisher KeyEventPublisher
- keyPressPublisher KeyEventPublisher
- keyUpPublisher KeyEventPublisher
- mouseDownPublisher MouseEventPublisher
- mouseUpPublisher MouseEventPublisher
- mouseMovePublisher MouseEventPublisher
- mouseWheelPublisher MouseEventPublisher
- boundsChangedPublisher EventPublisher
- sizeChangedPublisher EventPublisher
- maxSize Size
- minSize Size
- background Brush
- cursor Cursor
- suspended bool
- visible bool
- enabled bool
- name2Property map[string]Property
- enabledProperty Property
- enabledChangedPublisher EventPublisher
- visibleProperty Property
- visibleChangedPublisher EventPublisher
- focusedProperty Property
- focusedChangedPublisher EventPublisher
- calcTextSizeInfoPrev *calcTextSizeInfo
- }
只列出了属性, 没有列出方法. 但也可以看出来ui这个库开放的接口非常少. 而walk这个库, 该有的都有了, 接口非常丰富. 实现的控件非常多, 甚至连webview都有, 例子也丰富不少.
需要注意的这个库里面的控件是基于原生控件的, 而不是自己绘制的
walk使用
有点类似flutter中的申明式构建界面, 但是没有提供代码初始化的回调^^.
win使用
walk内部调用了win, 而win就干了一件事, 把win32 api几乎所有相关的声明都导成了go.
比如win32里面的ShowWindow, 是这么导出的:
这样我们用go来调用win32 api, 跟c基本没差别, 除了语法上的略微差别. 我试用了下, 还是有个把方法没有导出. 可以按照这个方式自己导出.
既然该有的win32接口都有了, 那么就用go创建一个最简单的windows窗口吧
func main() {
hInst := GetModuleHandle(nil)
hIcon := LoadIcon(0, MAKEINTRESOURCE(IDI_APPLICATION))
hCursor := LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW))
var wc WNDCLASSEX
wc.CbSize = uint32(unsafe.Sizeof(wc))
wc.LpfnWndProc = syscall.NewCallback(wndProc)
wc.HInstance = hInst
wc.HIcon = hIcon
wc.HCursor = hCursor
wc.HbrBackground = COLOR_WINDOW + 1
wc.LpszClassName = syscall.StringToUTF16Ptr("go windwow")
wc.Style = CS_HREDRAW | CS_VREDRAW
RegisterClassEx(&wc)
hWnd := CreateWindowEx(
0,
syscall.StringToUTF16Ptr("go windwow"),
syscall.StringToUTF16Ptr("go windwow"),
WS_OVERLAPPEDWINDOW,
400,
200,
640,
480,
0,
0,
hInst,
nil)
ShowWindow(hWnd, SW_SHOW)
UpdateWindow(hWnd)
var msg MSG
for {
if (GetMessage(&msg, 0, 0, 0) == TRUE) {
TranslateMessage(&msg)
DispatchMessage(&msg)
} else {
break
}
}
}
func wndProc(hwnd HWND, msg uint32, wParam, lParam uintptr) (result uintptr) {
var ps PAINTSTRUCT
switch msg {
case WM_PAINT:
hdc := BeginPaint(hwnd, &ps)
var lb LOGBRUSH
lb.LbStyle = BS_SOLID
lb.LbColor = 0xff000
lb.LbHatch = 0
hPen := HGDIOBJ(ExtCreatePen(PS_SOLID, 2, &lb, 0, nil))
hOldOpen := SelectObject(hdc, hPen)
var pt POINT
MoveToEx(hdc, 0, 0, &pt)
LineTo(hdc, 100, 100)
EndPaint(hwnd, &ps)
SelectObject(hdc, hOldOpen)
DeleteObject(hPen)
break
case WM_DESTROY:
PostQuitMessage(0)
break
default:
return DefWindowProc(hwnd, msg, wParam, lParam)
}
return 0
}
是不是基本与c的写法一模一样, 包括命名. 因此用go(win), 也能像c/c++一样开发windows界面, 只用稍微切换下语法.
而walk虽然把传统win32 api和控件封装成了对象, 把基于消息的事件包装成了回调, 封装出了canvs, 也有布局容器BoxLayout, 做做简单的界面还是很方便的, 但是其本质还是基于windows原有控件, 想自由布局, 定制界面, 性能方面还是很受限.
个人感觉可以win为基础封装自己的库, 比如用go把duilib翻译一遍, 这就又是另一番苦力活了.
如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。