在fyne-io中如何创建包含不同对象类型的表格?

huangapple go评论88阅读模式
英文:

How to make a table with different object types in fyne-io?

问题

我使用fyne-io来创建用户界面。在一个表格中,我想要一些带有超链接的单元格,其他单元格则使用Label。

我尝试了一下,但是没有起作用:

package main

import (
	"fmt"

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

func setDefaultColumnsWidth(table *widget.Table) {
	table.SetColumnWidth(0, 130)
	table.SetColumnWidth(1, 150)
	table.SetColumnWidth(2, 160)
	table.SetColumnWidth(3, 200)
	table.SetColumnWidth(4, 400)
	table.SetColumnWidth(5, 150)
	table.SetColumnWidth(6, 250)
	table.SetColumnWidth(7, 110)
	table.SetColumnWidth(8, 80)
}

func main() {

	application := app.New()
	win := application.NewWindow("Test GUI")

	data := [][]string{{"ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff"},
		{"ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff"},
		{"ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff"}}


	tableData := widget.NewTable(
		func() (int, int) {
			return len(data), len(data[0])
		},
		func() fyne.CanvasObject {
			label := widget.NewLabel("")
			return label
		},
		func(i widget.TableCellID, o fyne.CanvasObject) {
			switch o.(type) {
			case *widget.Label:
				label := o.(*widget.Label)
				label.SetText(data[i.Row][i.Col])

			case *widget.Hyperlink:
				fmt.Println("Found Hyperlink")
				hyperlink := o.(*widget.Hyperlink)


				// hyperlink.SetText(data[i.Row][i.Col])
				hyperlink.SetText("aaaaaaa")
			}

		})
	setDefaultColumnsWidth(tableData)
	id := widget.TableCellID{Row: 1, Col: 1}
	hyperlink := widget.NewHyperlink("TUTU", nil)
	obj := fyne.CanvasObject(hyperlink)
	fmt.Println("UpdateCell...")
	tableData.UpdateCell(id, obj)

	label := widget.NewLabel("My table :")
	button := widget.NewButton("Close", func() {
		application.Quit()
	})

	container := layout.NewBorderLayout(label, button, nil, nil)
	box := fyne.NewContainerWithLayout(container, label, tableData, button)
	win.SetContent(box)

	win.Resize(fyne.NewSize(1800, 400))
	win.ShowAndRun()
}

我该怎么做?

我看到了"Found Hyperlink"的消息,但是超链接没有显示出来。

为什么o.(type)等于*widget.Hyperlink,但超链接没有显示出来?

英文:

I use fyne-io to make an user interface. In a table, I want some cells with hyperlink and others with Label .

I try it but it doesn't work :

package main
import (
"fmt"
"fyne.io/fyne"
"fyne.io/fyne/app"
"fyne.io/fyne/layout"
"fyne.io/fyne/widget"
)
func setDefaultColumnsWidth(table *widget.Table) {
table.SetColumnWidth(0, 130)
table.SetColumnWidth(1, 150)
table.SetColumnWidth(2, 160)
table.SetColumnWidth(3, 200)
table.SetColumnWidth(4, 400)
table.SetColumnWidth(5, 150)
table.SetColumnWidth(6, 250)
table.SetColumnWidth(7, 110)
table.SetColumnWidth(8, 80)
}
func main() {
application := app.New()
win := application.NewWindow("Test GUI")
data := [][]string{{"ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff"},
{"ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff"},
{"ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff", "ffffffffffffff"}}
tableData := widget.NewTable(
func() (int, int) {
return len(data), len(data[0])
},
func() fyne.CanvasObject {
label := widget.NewLabel("")
return label
},
func(i widget.TableCellID, o fyne.CanvasObject) {
switch o.(type) {
case *widget.Label:
label := o.(*widget.Label)
label.SetText(data[i.Row][i.Col])
case *widget.Hyperlink:
fmt.Println("Found Hyperlink")
hyperlink := o.(*widget.Hyperlink)
//	hyperlink.SetText(data[i.Row][i.Col])
hyperlink.SetText("aaaaaaa")
}
})
setDefaultColumnsWidth(tableData)
id := widget.TableCellID{Row: 1, Col: 1}
hyperlink := widget.NewHyperlink("TUTU", nil)
obj := fyne.CanvasObject(hyperlink)
fmt.Println("UpdateCell...")
tableData.UpdateCell(id, obj)
label := widget.NewLabel("My table :")
button := widget.NewButton("Close", func() {
application.Quit()
})
container := layout.NewBorderLayout(label, button, nil, nil)
box := fyne.NewContainerWithLayout(container, label, tableData, button)
win.SetContent(box)
win.Resize(fyne.NewSize(1800, 400))
win.ShowAndRun()
}

How can I do ?

I see message of "fmt.Println("Found Hyperlink")" but hyperlink isn't displayed.

Why o.(type) equals to *widget.Hyperlink and hyperlink isn't displayed ?

答案1

得分: 1

似乎问题是标签没有被销毁并覆盖了新创建的超链接。我找不到上述问题的解决方案,但提出了替代方案,因为fyne API处于开发阶段,许多内部功能无法访问,解决方案可能会随时间改变并简化。

package main

import (
  "image/color"

  "fyne.io/fyne/v2"
  "fyne.io/fyne/v2/app"
  "fyne.io/fyne/v2/layout"
  "fyne.io/fyne/v2/widget"
  "fyne.io/fyne/v2/canvas"
)

const HEIGHT float32 = 30

func setDefaultColumnsWidth(table *widget.Table) {
  colWidths := []float32{130, 150, 160, 200, 400, 150, 250, 110, 80}
  for idx, colWidth := range colWidths {
    table.SetColumnWidth(idx, colWidth)
  }
}

func main() {

  application := app.New()
  win := application.NewWindow("Test GUI")

  data := [][]fyne.CanvasObject{
    {widget.NewLabel("ffffffffffffff"), widget.NewHyperlink("TUTU", nil), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff")},
    {widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewHyperlink("ffffffffffffff", nil)},
    {widget.NewHyperlink("TUTU", nil), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff")},
  }

  tableData := widget.NewTable(
    func() (int, int) {
      return len(data), len(data[0])
    },
    func() fyne.CanvasObject {
      c := fyne.NewContainerWithoutLayout()
      r := canvas.NewRectangle(color.White)
      r.SetMinSize(fyne.NewSize(0, HEIGHT))
      r.Resize(fyne.NewSize(0, HEIGHT))
      c.AddObject(r)
      return c
    },
    func(cell widget.TableCellID, o fyne.CanvasObject) {
      container := o.(*fyne.Container)
      var obj fyne.CanvasObject = data[cell.Row][cell.Col]
      container.AddObject(obj)
      container.Refresh()
  })

  setDefaultColumnsWidth(tableData)

  label := widget.NewLabel("My table :")
  button := widget.NewButton("Close", func() {
    application.Quit()
  })

  container := layout.NewBorderLayout(label, button, nil, nil)
  box := fyne.NewContainerWithLayout(container, label, tableData, button)
  win.SetContent(box)

  win.Resize(fyne.NewSize(1800, 400))
  win.ShowAndRun()

}

输出:
在fyne-io中如何创建包含不同对象类型的表格?

英文:

It seem the issue is that label does not get destroyed and overlaps newly created hyperlink. I am not able to find the solution for above problem but came up with alternative solution since fyne API are in dev phase many internal functionalities are not accessible and may get changed the solution may changed overtime and get simplefied.

package main

import (
  "image/color"

  "fyne.io/fyne/v2"
  "fyne.io/fyne/v2/app"
  "fyne.io/fyne/v2/layout"
  "fyne.io/fyne/v2/widget"
  "fyne.io/fyne/v2/canvas"
)

const HEIGHT float32 = 30

func setDefaultColumnsWidth(table *widget.Table) {
  colWidths := []float32{130, 150, 160, 200, 400, 150, 250, 110, 80}
  for idx, colWidth := range colWidths {
    table.SetColumnWidth(idx, colWidth)
  }
}

func main() {

  application := app.New()
  win := application.NewWindow("Test GUI")

  data := [][]fyne.CanvasObject{
    {widget.NewLabel("ffffffffffffff"), widget.NewHyperlink("TUTU", nil), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff")},
    {widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewHyperlink("ffffffffffffff", nil)},
    {widget.NewHyperlink("TUTU", nil), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff"), widget.NewLabel("ffffffffffffff")},
  }

  tableData := widget.NewTable(
    func() (int, int) {
      return len(data), len(data[0])
    },
    func() fyne.CanvasObject {
      c := fyne.NewContainerWithoutLayout()
      r := canvas.NewRectangle(color.White)
      r.SetMinSize(fyne.NewSize(0, HEIGHT))
      r.Resize(fyne.NewSize(0, HEIGHT))
      c.AddObject(r)
      return c
    },
    func(cell widget.TableCellID, o fyne.CanvasObject) {
      container := o.(*fyne.Container)
      var obj fyne.CanvasObject = data[cell.Row][cell.Col]
      container.AddObject(obj)
      container.Refresh()
  })

  setDefaultColumnsWidth(tableData)

  label := widget.NewLabel("My table :")
  button := widget.NewButton("Close", func() {
    application.Quit()
  })

  container := layout.NewBorderLayout(label, button, nil, nil)
  box := fyne.NewContainerWithLayout(container, label, tableData, button)
  win.SetContent(box)

  win.Resize(fyne.NewSize(1800, 400))
  win.ShowAndRun()

}

Output:
在fyne-io中如何创建包含不同对象类型的表格?

答案2

得分: 1

我联系了Fyne Slack群组,他们推荐的解决方案是将这两个元素封装在一个容器中,并在更新回调函数中只显示所需的元素。

创建单元格回调函数:

func() fyne.CanvasObject {
    label := widget.NewLabelWithStyle("", fyne.TextAlignLeading, fyne.TextStyle{})
    hyperlink := widget.NewHyperlink("", nil)
    hyperlink.Hide()
    return container.NewMax(label, hyperlink)
}

更新回调函数:

func(i widget.TableCellID, o fyne.CanvasObject) {

    container := o.(*fyne.Container)
    label := container.Objects[0].(*widget.Label)
    hyperlink := container.Objects[1].(*widget.Hyperlink)

    switch i.Col {
    case 0:
    case 5:
        label.Hide()
        hyperlink.Hidden = false
        hyperlink.SetText("Hi!")
        hyperlink.SetURL(url.Parse("https://stackoverflow.com"))

    default:
        hyperlink.Hide()
        label.Hidden = false
        label.SetText("Hello")
    }
}

以上是翻译好的内容,请查看。

英文:

I contacted the Fyne Slack group and a recommended solution is to encapsulate both elements in a container and display only the desired element at the update callback function

Create cell callback function :

func() fyne.CanvasObject {
label := widget.NewLabelWithStyle("", fyne.TextAlignLeading, fyne.TextStyle{})
hyperlink := widget.NewHyperlink("", nil)
hyperlink.Hide()
return container.NewMax(label, hyperlink)
}

Updade callback function :

func(i widget.TableCellID, o fyne.CanvasObject) {
container := o.(*fyne.Container)
label := container.Objects[0].(*widget.Label)
hyperlink := container.Objects[1].(*widget.Hyperlink)
switch i.Col {
case 0:
case 5:
label.Hide()
hyperlink.Hidden = false
hyperlink.SetText("Hi!")
hyperlink.SetURL(url.Parse("https://stackoverflow.com"))
default:
hyperlink.Hide()
label.Hidden = false
label.SetText("Hello")
}
}

答案3

得分: 0

有关如何使用container.NewMaxTable.SetColumnWidth创建更复杂的表格的更完整的写作可以在以下链接中找到:

在fyne-io中如何创建包含不同对象类型的表格?

两个主要的技巧是设置一个容器而不是单个小部件:

container.NewMax(widget.NewLabel("template11"), widget.NewIcon(nil))

然后在回调函数中适当地隐藏或显示项目:

l := o.(*fyne.Container).Objects[0].(*widget.Label)
i := o.(*fyne.Container).Objects[1].(*widget.Icon)
l.Show()
i.Hide()
switch id.Col {
case 2:
    l.Hide()
    i.Show()
    i.SetResource(getIcon(id.Row))
case 0:
    l.SetText("hostname")
}

详细内容请阅读https://fynelabs.com/2022/12/30/building-complex-tables-with-fyne/

英文:

There is a more complete writeup about how to use container.NewMax and Table.SetColumnWidth to create more complex tables. The example steps through the code for this table:

在fyne-io中如何创建包含不同对象类型的表格?

The two main tricks are to set up a container instead of a single widget:

container.NewMax(widget.NewLabel("template11"), widget.NewIcon(nil))

And then to hide or show items appropriately in the callback:

l := o.(*fyne.Container).Objects[0].(*widget.Label)
i := o.(*fyne.Container).Objects[1].(*widget.Icon)
l.Show()
i.Hide()
switch id.Col {
case 2:
    l.Hide()
    i.Show()
    i.SetResource(getIcon(id.Row))
case 0:
    l.SetText("hostname")
}

Read more at https://fynelabs.com/2022/12/30/building-complex-tables-with-fyne/

huangapple
  • 本文由 发表于 2022年9月1日 23:08:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/73571674.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定