如何扩展fyne的BaseWidget – Go会报错”type *SimpleCard没有super字段或方法”

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

How to extend fyne BaseWidget - go gives error "type *SimpleCard has no field or method super"

问题

我正在尝试扩展fyne小部件,使其具有带有背景的简单可点击内容。我搜索了fyne小部件,找到了一个类似的示例,可以用作起点,类似于List/ListItem。

我基本上复制了列表项代码并进行了一些调整。
它看起来与fyne文档中的简单示例相似。但由于某种未知的原因,Go给了我一个错误,我不知道原因是什么,也不知道如何修复它:

  1. custom_widget/simple_card.go:80:24: c.card.super undefined (type *SimpleCard has no field or method super)

这是模块的代码(custom_widget/simple_card.go):

  1. package custom_widget
  2. import (
  3. "fyne.io/fyne/v2"
  4. "fyne.io/fyne/v2/canvas"
  5. "fyne.io/fyne/v2/theme"
  6. "fyne.io/fyne/v2/widget"
  7. "log"
  8. )
  9. // 声明符合接口的类型。
  10. var _ fyne.Widget = (*SimpleCard)(nil)
  11. var _ fyne.Tappable = (*SimpleCard)(nil)
  12. type SimpleCard struct {
  13. widget.BaseWidget
  14. onTapped func()
  15. background *canvas.Rectangle
  16. content fyne.CanvasObject
  17. selected bool
  18. }
  19. func NewSimpleCard(content fyne.CanvasObject, tapped func()) *SimpleCard {
  20. card := &SimpleCard{onTapped: tapped, content: content}
  21. card.ExtendBaseWidget(card)
  22. return card
  23. }
  24. // CreateRenderer是一个将此custom_widget链接到其渲染器的私有方法。
  25. func (c *SimpleCard) CreateRenderer() fyne.WidgetRenderer {
  26. c.ExtendBaseWidget(c)
  27. c.background = canvas.NewRectangle(theme.SelectionColor())
  28. c.background.Hide()
  29. objects := []fyne.CanvasObject{c.background, c.content}
  30. // NewBaseRenderer和BaseRenderer是从
  31. // https://github.com/fyne-io/fyne/blob/master/internal/widget/base_renderer.go
  32. // 复制过来的,因为在fyne中,这些功能被标记为internal!?
  33. return &SimpleCardRenderer{NewBaseRenderer(objects), c}
  34. }
  35. func (c *SimpleCard) Tapped(_ *fyne.PointEvent) {
  36. log.Println("我被点击了")
  37. if c.onTapped != nil {
  38. c.selected = true
  39. c.Refresh()
  40. c.onTapped()
  41. }
  42. }
  43. // 声明符合WidgetRenderer接口的类型。
  44. var _ fyne.WidgetRenderer = (*SimpleCardRenderer)(nil)
  45. type SimpleCardRenderer struct {
  46. BaseRenderer
  47. card *SimpleCard
  48. }
  49. // MinSize计算SimpleCardRenderer的最小大小。
  50. // 这基于状态指示器的大小和子对象的大小。
  51. func (c *SimpleCardRenderer) MinSize() fyne.Size {
  52. return c.card.content.MinSize()
  53. }
  54. // 布局SimpleCardRenderer custom_widget的组件。
  55. func (c *SimpleCardRenderer) Layout(size fyne.Size) {
  56. c.card.background.Resize(size)
  57. c.card.content.Resize(size)
  58. }
  59. func (c *SimpleCardRenderer) Refresh() {
  60. if c.card.selected {
  61. c.card.background.FillColor = theme.SelectionColor()
  62. c.card.background.Show()
  63. } else {
  64. c.card.background.Hide()
  65. }
  66. c.card.background.Refresh()
  67. canvas.Refresh(c.card.super()) // 编译器错误!
  68. }

希望这可以帮助你解决问题。

英文:

I'm trying to extend fyne widget to have a simple clickable content with background.
I searched fyne widgets to find an example that could be used as a starter and found something similar in List/ListItem.

I basically copied the list item code and adapted it a little bit.
It does look similar to the simpler example on fyne documentation.
But for some unknown reason go gives me an error and I don't know what the cause is or how I can fix it:

  1. custom_widget/simple_card.go:80:24: c.card.super undefined (type *SimpleCard has no field or method super)

Here is the code of the module (custom_widget/simple_card.go):

  1. package custom_widget
  2. import (
  3. "fyne.io/fyne/v2"
  4. "fyne.io/fyne/v2/canvas"
  5. "fyne.io/fyne/v2/theme"
  6. "fyne.io/fyne/v2/widget"
  7. "log"
  8. )
  9. // Declare conformity with interfaces.
  10. var _ fyne.Widget = (*SimpleCard)(nil)
  11. var _ fyne.Tappable = (*SimpleCard)(nil)
  12. type SimpleCard struct {
  13. widget.BaseWidget
  14. onTapped func()
  15. background *canvas.Rectangle
  16. content fyne.CanvasObject
  17. selected bool
  18. }
  19. func NewSimpleCard(content fyne.CanvasObject, tapped func()) *SimpleCard {
  20. card := &SimpleCard{onTapped: tapped, content: content}
  21. card.ExtendBaseWidget(card)
  22. return card
  23. }
  24. // CreateRenderer is a private method to Fyne which links this custom_widget to its renderer.
  25. func (c *SimpleCard) CreateRenderer() fyne.WidgetRenderer {
  26. c.ExtendBaseWidget(c)
  27. c.background = canvas.NewRectangle(theme.SelectionColor())
  28. c.background.Hide()
  29. objects := []fyne.CanvasObject{c.background, c.content}
  30. // NewBaseRenderer and BaseRenderer are copied from
  31. // https://github.com/fyne-io/fyne/blob/master/internal/widget/base_renderer.go
  32. // because the functionality is marked internal in fyne !?
  33. return &SimpleCardRenderer{NewBaseRenderer(objects), c}
  34. }
  35. func (c *SimpleCard) Tapped(_ *fyne.PointEvent) {
  36. log.Println("I have been tapped")
  37. if c.onTapped != nil {
  38. c.selected = true
  39. c.Refresh()
  40. c.onTapped()
  41. }
  42. }
  43. // Declare conformity with the WidgetRenderer interface.
  44. var _ fyne.WidgetRenderer = (*SimpleCardRenderer)(nil)
  45. type SimpleCardRenderer struct {
  46. BaseRenderer
  47. card *SimpleCard
  48. }
  49. // MinSize calculates the minimum size of a SimpleCardRenderer.
  50. // This is based on the size of the status indicator and the size of the child object.
  51. func (c *SimpleCardRenderer) MinSize() fyne.Size {
  52. return c.card.content.MinSize()
  53. }
  54. // Layout the components of the SimpleCardRenderer custom_widget.
  55. func (c *SimpleCardRenderer) Layout(size fyne.Size) {
  56. c.card.background.Resize(size)
  57. c.card.content.Resize(size)
  58. }
  59. func (c *SimpleCardRenderer) Refresh() {
  60. if c.card.selected {
  61. c.card.background.FillColor = theme.SelectionColor()
  62. c.card.background.Show()
  63. } else {
  64. c.card.background.Hide()
  65. }
  66. c.card.background.Refresh()
  67. canvas.Refresh(c.card.super()) // compiler error !
  68. }

答案1

得分: 1

删除您创建的所有渲染器类型,并在CreateRenderer中只返回widget.NewSimpleRenderer(container.NewMax(c.background, c.content))。这比您想象的要简单。

从主要小部件中复制代码通常不是最好的方法,因为我们有快捷方式和/或必须支持比您自己的小部件更多的功能。

英文:

Remove all of the renderer type you created and in the CreateRenderer just return widget.NewSimpleRenderer(container
.NewMax(c.background, c.content))
. It is simpler than you think.

Copying code out of the main widgets is often not the best way as we have shortcuts and/or must support more functionality than your own widgets.

huangapple
  • 本文由 发表于 2022年10月6日 17:08:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/73971257.html
匿名

发表评论

匿名网友

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

确定