我正在尝试制作一个文件选择小部件(几乎在我负责的每个开发中都需要它)。该小部件由一个标签、一个条目和一个按钮(按此顺序)组成,并且它们都水平显示在同一行上。
我希望避免(如果可能的话)制作一个全新的自定义小部件,因为 100% 的功能已经存在于 sandard fyne 小部件中。所以我的想法是制作一个自定义布局并将我的小部件放在那里。
问题是,由于我的构造函数返回一个 fyne.Container,我无法访问我需要访问的 Entry.Text 字段。
当然,container.Objects[1].(widgets.Entry).Text
每次我需要访问它时我都可以这样做,但这似乎不直观。
所以然后我想我会扩展 fyne.Container 以通过一种方法将文本返回给我,但是似乎容器没有类似的东西ExtendBaseWidget()
来获得容器的所有功能。
这是我到目前为止的工作代码:
package fyne_custom
import (
"os"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
"github.com/sqweek/dialog"
)
type FileChoiceLayout struct {
Label, Entry, Button fyne.CanvasObject
}
func (f FileChoiceLayout) MinSize(_ []fyne.CanvasObject) fyne.Size {
total := fyne.NewSize(0, 0)
total = total.Add(f.Label.MinSize())
total = total.Add(f.Entry.MinSize())
total = total.Add(f.Button.MinSize())
return total
}
func (f FileChoiceLayout) Layout(items []fyne.CanvasObject, size fyne.Size) {
topLeft := fyne.NewPos(0, 0)
for _, item := range items {
if item == f.Label {
item.Move(topLeft)
item.Resize(item.MinSize())
topLeft = topLeft.Add(fyne.NewPos(item.MinSize().Width, 0))
} else if item == f.Entry {
item.Move(topLeft)
width := size.Width - f.Label.MinSize().Width - f.Button.MinSize().Width
item.Resize(fyne.NewSize(width, item.MinSize().Height))
topLeft = topLeft.Add(fyne.NewPos(width, 0))
} else if item == f.Button {
item.Move(topLeft)
item.Resize(item.MinSize())
}
}
}
func NewFileChoice(labelText, placeHolder, buttonText string) (*fyne.Container, *widget.Entry) {
label := widget.NewLabel(labelText)
entry := widget.NewEntry()
entry.PlaceHolder = placeHolder
button := widget.NewButton(buttonText, func() {
cwd, _ := os.Getwd()
file, err := dialog.File().Load()
if err != nil {
file = ""
}
if file != "" {
entry.SetText(file)
}
os.Chdir(cwd)
})
container := container.New(&FileChoiceLayout{Label: label, Entry: entry, Button: button}, label, entry, button)
return container, entry
}
到目前为止,我发现的临时解决方法是不仅返回容器,还返回条目小部件以访问其文本字段。
我在想一定有更好的方法来做到这一点,但我似乎找不到。任何想法将不胜感激!