我对 Go 很满意,我正在尝试开始使用 Gio(或 Gioui),所以我是 Gio 的初学者。 我有一个在窗口上绘制文本和按钮的代码(代码和屏幕截图)。我有两个问题:
我的代码是
import (
"fmt"
"log"
"os"
"gioui.org/app"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/text"
"gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material"
)
func main() {
go func() {
w := new(app.Window)
w.Option(app.Title("Hello World"))
w.Option(app.MaxSize(unit.Dp(400), unit.Dp(600)))
if err := draw(w); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
app.Main()
}
func draw(w *app.Window) error {
var ops op.Ops
var lblButton widget.Clickable
var btnClickArea widget.Clickable
th := material.NewTheme()
btn := layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
btn := material.Button(th, &btnClickArea, "Button1")
return btn.Layout(gtx)
},
)
columns := layout.Flex{Axis: layout.Horizontal, Spacing: layout.SpaceAround}
for {
switch e := w.Event().(type) {
case app.FrameEvent:
gtx := app.NewContext(&ops, e)
if lblButton.Clicked(gtx) {
fmt.Println("the label was clicked")
}
if btnClickArea.Clicked(gtx) {
fmt.Println("button1 was clicked")
}
layout.Flex{
Axis: layout.Vertical,
Spacing: layout.SpaceStart,
}.Layout(gtx,
layout.Rigid(
layout.Spacer{Height: unit.Dp(250)}.Layout,
),
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(th, unit.Sp(50), "hello world")
lbl.Alignment = text.Middle
lblButton.Layout(gtx, lbl.Layout)
return lbl.Layout(gtx)
},
),
layout.Rigid(
func(gtx layout.Context) layout.Dimensions {
return columns.Layout(gtx, btn)
},
),
)
e.Frame(gtx.Ops)
case app.DestroyEvent:
return e.Err
}
}
return nil
}
您似乎想要的是两个嵌套的
layout.Flex
。顶层窗口将窗口垂直划分为用于文本的刚性区域和用于其余空间的灵活区域。然后水平弯曲将底部区域分为两个窗格。然后,您可以在右侧窗格内使用插图和方向来定位按钮。这是一个工作示例:
package main
import (
"fmt"
"image"
"log"
"os"
"gioui.org/app"
"gioui.org/layout"
"gioui.org/op"
"gioui.org/text"
"gioui.org/unit"
"gioui.org/widget"
"gioui.org/widget/material"
)
func main() {
go func() {
w := new(app.Window)
w.Option(app.Title("Hello World"))
w.Option(app.MaxSize(unit.Dp(400), unit.Dp(600)))
if err := draw(w); err != nil {
log.Fatal(err)
}
os.Exit(0)
}()
app.Main()
}
func draw(w *app.Window) error {
var ops op.Ops
var lblButton widget.Clickable
var btnClickArea widget.Clickable
th := material.NewTheme()
for {
switch e := w.Event().(type) {
case app.FrameEvent:
gtx := app.NewContext(&ops, e)
if lblButton.Clicked(gtx) {
fmt.Println("the label was clicked")
}
if btnClickArea.Clicked(gtx) {
fmt.Println("button1 was clicked")
}
// This flex splits the window vertically.
layout.Flex{
Axis: layout.Vertical,
}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(th, unit.Sp(50), "hello world")
lbl.Alignment = text.Middle
// Here we use the material.Clickable wrapper func to animate button clicks.
return material.Clickable(gtx, &lblButton, lbl.Layout)
}),
layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
// This flex splits the bottom pane horizontally.
return layout.Flex{}.Layout(gtx,
layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
// This returns an empty left-hand pane.
return layout.Dimensions{Size: gtx.Constraints.Min}
}),
layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
// Here we position the button at the "north" or top-center of the available space.
return layout.N.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
// Here we set the minimum constraints to zero. This allows our button to be smaller
// than the entire right-side pane in the UI. Without this change, the button is forced
// to occupy all of the space.
gtx.Constraints.Min = image.Point{}
// Here we inset the button a little bit on all sides.
return layout.UniformInset(8).Layout(gtx,
material.Button(th, &btnClickArea, "Button1").Layout,
)
})
}),
)
}),
)
e.Frame(gtx.Ops)
case app.DestroyEvent:
return e.Err
}
}
return nil
}