gpt4 book ai didi

Go and Fyne - 需要对话框响应并启用/禁用提交按钮

转载 作者:行者123 更新时间:2023-12-01 22:24:55 25 4
gpt4 key购买 nike

刚开始研究 Go 和 Fyne。使用从示例中获得的信息编写测试 CRUD 程序后,我需要解决以下问题:

  • 我需要一个初始对话框或类似的,以便允许选择现有记录或"new"来指示新记录。我现有的对话框不能充分处理这个问题。
  • 如果数据没有更改,我需要能够启用/禁用提交按钮以允许或禁止更新。
  • 程序编译没有错误,但是“go vet”和 VsCode 指示(例如对于 line):
  •      {"Given Names:", arwWidgets[I_NDX_GIVEN]},
     go vet shows:
    ERROR: "unknown field 'Key' in struct literal of type widget.FormItem",
    however, if I include a key, compiler fails.
  • 作为 Go 和 Fyne 的新手,可能存在根本性错误。

  • 测试程序如下:
    package main
    // Dependency: local directory "data".
    import (
    "errors"
    "io/ioutil"
    "log"
    "os"
    "strings"

    "fyne.io/fyne"
    "fyne.io/fyne/app"
    "fyne.io/fyne/dialog"
    "fyne.io/fyne/layout"
    "fyne.io/fyne/widget"
    )

    const BY_SEP byte = byte('|')
    const I_ARRAY_LEN int = 10
    const I_NDX_GIVEN int = 0
    const I_NDX_FAMILY int = 1
    const I_NDX_TITLE int = 2
    const I_NDX_ADDR1 int = 3
    const I_NDX_ADDR2 int = 4
    const I_NDX_ADDR3 int = 5
    const I_NDX_STATE int = 6
    const I_NDX_ZIP int = 7
    const I_NDX_TELE1 int = 8
    const I_NDX_TELE2 int = 9

    var _arsOldData [I_ARRAY_LEN]string
    var _arsNewData [I_ARRAY_LEN]string
    var _tfDataHasChanged bool
    var _sKey string
    var _arwEntryWidgets [I_ARRAY_LEN]*widget.Entry
    var _wApp fyne.App
    var _wWindow fyne.Window
    var _wModal widget.PopUp
    var _wFormKeyEntry widget.Form

    //-------------------------------------------------------------------------------

    func main() {
    log.Println("In fytest01")
    _, err := os.Stat("./data/")
    if err != nil {
    log.Println("You need to create directory: 'data'")
    os.Exit(1)
    }
    //fnReadData()
    _wApp := app.New()
    _wWindow := _wApp.NewWindow("Customer Details")
    //_wFormKeyEntry := fnCreateKeyForm()
    wFormMain := fnCreateMainForm()
    //_wModal := widget.NewModalPopUp(_wFormKeyEntry, _wWindow.Canvas())
    _wWindow.Resize(fyne.NewSize(500, 400))
    _wWindow.CenterOnScreen()
    _wWindow.SetContent(widget.NewVBox(
    wFormMain,
    widget.NewGroup("",
    fyne.NewContainerWithLayout(layout.NewGridLayout(2),
    widget.NewButton("Exit", func() {
    _wApp.Quit()
    }),
    widget.NewButton("Submit", func() {
    log.Println("Submit button pressed")
    err := fnUpdateData()
    if err == nil {
    dialog.ShowInformation("Information", "Data was updated", _wWindow)
    wEntryForKey := widget.NewEntry()
    wEntryForKey.SetPlaceHolder("Enter Key (4) : ")
    wEntryForKey.OnChanged = func(sKey string) {
    log.Println("Entered", sKey)
    if len(sKey) == 4 {
    _sKey = sKey
    }
    if len(_sKey) == 4 {
    dialog.ShowInformation("Information", "Key "+_sKey+" has been entered - press OK", _wWindow)
    fnReadData()
    fnRefreshWidgetData()
    }
    }
    dialog.ShowCustom("Enter Customer Key", "OK", wEntryForKey, _wWindow)
    } else {
    dialog.ShowError(err, _wWindow)
    }
    }),
    ))),
    )
    //fnShowKeyEntryDialog()

    wEntryForKey := widget.NewEntry()
    wEntryForKey.SetPlaceHolder("Enter Key (4) : ")
    wEntryForKey.OnChanged = func(sKey string) {
    log.Println("Entered", sKey)
    if len(sKey) == 4 {
    _sKey = sKey
    }
    if len(_sKey) == 4 {
    dialog.ShowInformation("Information", "Key "+_sKey+" has been entered - press OK", _wWindow)
    fnReadData()
    fnRefreshWidgetData()
    }
    }
    dialog.ShowCustom("Enter Customer Key", "OK", wEntryForKey, _wWindow)
    _wWindow.ShowAndRun()
    //_wModal.Show()
    }

    //-------------------------------------------------------------------------------

    func fnCreateAllEntryWidgets() {
    _arwEntryWidgets[I_NDX_GIVEN] = fnCreateSingleEntryWidget(I_NDX_GIVEN)
    _arwEntryWidgets[I_NDX_FAMILY] = fnCreateSingleEntryWidget(I_NDX_FAMILY)
    _arwEntryWidgets[I_NDX_TITLE] = fnCreateSingleEntryWidget(I_NDX_TITLE)
    _arwEntryWidgets[I_NDX_ADDR1] = fnCreateSingleEntryWidget(I_NDX_ADDR1)
    _arwEntryWidgets[I_NDX_ADDR2] = fnCreateSingleEntryWidget(I_NDX_ADDR2)
    _arwEntryWidgets[I_NDX_ADDR3] = fnCreateSingleEntryWidget(I_NDX_ADDR3)
    _arwEntryWidgets[I_NDX_STATE] = fnCreateSingleEntryWidget(I_NDX_STATE)
    _arwEntryWidgets[I_NDX_ZIP] = fnCreateSingleEntryWidget(I_NDX_ZIP)
    _arwEntryWidgets[I_NDX_TELE1] = fnCreateSingleEntryWidget(I_NDX_TELE1)
    _arwEntryWidgets[I_NDX_TELE2] = fnCreateSingleEntryWidget(I_NDX_TELE2)
    }

    //-------------------------------------------------------------------------------

    func fnCreateSingleEntryWidget(iNdxData int) *widget.Entry {
    wEntry := widget.NewEntry()
    wEntry.SetText(_arsOldData[iNdxData])
    wEntry.OnChanged = func(sText string) {
    _arsNewData[iNdxData] = sText
    fnCheckIfDataHasChanged()
    }
    return wEntry
    }

    //-------------------------------------------------------------------------------

    func fnCreateFormFields(arwWidgets [I_ARRAY_LEN]*widget.Entry) []*widget.FormItem {
    return []*widget.FormItem{
    {"Given Names:", arwWidgets[I_NDX_GIVEN]},
    {"Family Name: ", arwWidgets[I_NDX_FAMILY]},
    {"Title: ", arwWidgets[I_NDX_TITLE]},
    {"Address Ln 1: ", arwWidgets[I_NDX_ADDR1]},
    {" '' Ln 2: ", arwWidgets[I_NDX_ADDR2]},
    {" '' Ln 3: ", arwWidgets[I_NDX_ADDR3]},
    {" '' State ", arwWidgets[I_NDX_STATE]},
    {" '' Zip: ", arwWidgets[I_NDX_ZIP]},
    {"Telephone 1: ", arwWidgets[I_NDX_TELE1]},
    {"Telephone 2: ", arwWidgets[I_NDX_TELE2]},
    }
    }

    //-------------------------------------------------------------------------------

    func fnCheckIfDataHasChanged() {
    var tfChanged bool = false
    for iNdxData := 0; !tfChanged && iNdxData < len(_arsOldData); iNdxData++ {
    tfChanged = (_arsNewData[iNdxData] != _arsOldData[iNdxData])
    }
    if tfChanged != _tfDataHasChanged {
    _tfDataHasChanged = tfChanged
    if tfChanged {
    // COULD NOT CREATE _wBtnSubmitMain AS A GLOBAL VARIABLE.
    //_wBtnSubmitMain.Show()
    //_wBtnSubmitMain.Enable()
    } else {
    //_wBtnSubmitMain.Disable()
    //_wBtnSubmitMain.Hide()
    }
    }
    }

    //-------------------------------------------------------------------------------

    func fnReadData() {
    _tfDataHasChanged = false
    log.Println("fnReadData: Key = " + _sKey)
    var sData string
    if len(_sKey) > 0 {
    arbData, _ := ioutil.ReadFile("./data/" + _sKey)
    if arbData != nil {
    sData = string(arbData)
    }
    }
    log.Println("fnReadData: sData = " + sData)

    /* CLEAR OLD DATA */
    for iNdxData := 0; iNdxData < I_ARRAY_LEN; iNdxData++ {
    _arsOldData[iNdxData] = ""
    }

    /* POPULATE DATA IF ANY */
    var iNdx1 int = 0
    var iNdxData int = 0
    var iLen int = len(sData)
    for iNdx2 := 0; iNdx2 < len(sData); iNdx2++ {
    if sData[iNdx2] == BY_SEP {
    _arsOldData[iNdxData] = sData[iNdx1:iNdx2]
    iNdx1 = iNdx2 + 1
    iNdxData++
    } else if iNdx2 == (iLen - 1) {
    _arsOldData[iNdxData] = sData[iNdx1 : iNdx2+1]
    }
    }
    for iNdx := 0; iNdx < I_ARRAY_LEN; iNdx++ {
    _arsNewData[iNdx] = _arsOldData[iNdx]
    }
    }

    //-------------------------------------------------------------------------------

    func fnUpdateData() error {
    if !_tfDataHasChanged {
    return errors.New("Data has not changed")
    }

    if len(_sKey) < 1 {
    _sKey = "9999"
    //dialog.ShowInformation("Information", "Default key of 9999 was used", _wWindow) // CAUSES ERROR
    }

    var sNewData string = ""
    for iNdxData, sVal := range _arsNewData {
    if strings.Index(sVal, "|") >= 0 {
    sVal = strings.ReplaceAll(sVal, "|", ":")
    }
    if iNdxData != I_ARRAY_LEN-1 {
    sNewData += sVal + string(BY_SEP)
    } else {
    sNewData += sVal
    }
    }
    log.Println("New Data = " + sNewData)
    var err error = ioutil.WriteFile("./data/"+_sKey, []byte(sNewData), 0644)
    if err == nil {
    for iNdxData := 0; iNdxData < len(_arsNewData); iNdxData++ {
    _arsOldData[iNdxData] = _arsNewData[iNdxData]
    }
    fnCheckIfDataHasChanged()
    }
    return err
    }

    //-------------------------------------------------------------------------------

    func fnCreateKeyForm() *widget.Form {
    wEntryKey := widget.NewEntry()
    return &widget.Form{
    Items: []*widget.FormItem{
    {"Key:", wEntryKey}},
    OnSubmit: func() {
    _sKey = wEntryKey.Text
    log.Println("Key = " + _sKey)
    fnReadData()
    log.Println("Data has been read")
    fnRefreshWidgetData()
    _wFormKeyEntry.Hide()
    //_wModal.Hide()
    },
    }
    }

    //-------------------------------------------------------------------------------

    //func fnCreateMainWindow() {
    // log.Println("Creating Main Window Form")
    // wFormMain := fnCreateMainForm()
    // log.Println("Creating Main Window Window")
    // _wWindow.SetContent( //widget.NewVBox(
    // wFormMain,
    // )
    //}

    //-------------------------------------------------------------------------------

    func fnCreateMainForm() *widget.Form {
    log.Println("Create form1 widgets")
    fnCreateAllEntryWidgets()
    log.Println("Create form1 FormFields")
    arwFormFields := fnCreateFormFields(_arwEntryWidgets)
    log.Println("Creating Form1")
    return &widget.Form{
    Items: arwFormFields,
    }
    }

    //-------------------------------------------------------------------------------

    func fnRefreshWidgetData() {
    for iNdx := 0; iNdx < I_ARRAY_LEN; iNdx++ {
    _arwEntryWidgets[iNdx].SetText(_arsNewData[iNdx])
    }
    }

    最佳答案

  • 您可以在开始窗口中添加一个“新建”按钮,填充默认值然后打开主窗口。那有意义吗?
  • 您可以通过创建提交按钮并将其直接传递给 SetContent 来创建它。 .您需要将其保存在一个变量中,以便您可以在某个时候调用 Disable()在上面。
  • submitButton := widget.NewButton("Submit", func() {
    log.Println("Submit button pressed")
    ...
    })
    _wWindow.SetContent(widget.NewVBox(
    wFormMain,
    widget.NewGroup("",
    fyne.NewContainerWithLayout(layout.NewGridLayout(2),
    widget.NewButton("Exit", func() {
    _wApp.Quit()
    }),
    submitButton,
    ))),
    )

    ...
    if dataChanged {
    submitButton.Enable()
    } else {
    submitButton.Disable()
    }
  • 我认为 go vet消息是说您应该命名结构文字中的所有字段(尽管我使用 Go 1.13 收到了不同的消息)。 Go 允许您按顺序或按名称添加值 - go vet告诉你按名称更安全(例如,如果字段被移动或插入到 FormItem 结构,那么你的代码将被破坏)。

  • IE:
        return []*widget.FormItem{
    { Text: "Given Names:", Widget: arwWidgets[I_NDX_GIVEN]},
    ...
  • 它还可以简化将所有全局变量放入结构的事情,然后您可以在结构上使用“方法”。 (有几个原因可以避免使用您可能已经知道的全局变量。我很欣赏这可能是从一个简单的测试开始的,但它可能是重构的好时机。)
  • 关于Go and Fyne - 需要对话框响应并启用/禁用提交按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60594776/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com