英文:
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()
}
英文:
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()
}
答案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.NewMax
和Table.SetColumnWidth
创建更复杂的表格的更完整的写作可以在以下链接中找到:
两个主要的技巧是设置一个容器而不是单个小部件:
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:
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/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论