Golang中Gotk3 grid.InsertRow的问题如何解决
Golang中Gotk3 grid.InsertRow的问题如何解决 我一直无法使用GTK3的Grid来插入额外的行。
我编写了一个最小示例来展示我的问题。可能我遗漏了什么。
任何反馈都表示感谢。
package main
import ("github.com/gotk3/gotk3/gtk")
import "fmt"
func main(){
gtk.Init(nil)
major:=gtk.GetMajorVersion(); minor:=gtk.GetMinorVersion()
fmt.Println(fmt.Sprintf("GTK version %d.%d",major,minor))
win,_ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
win.SetDefaultSize(500,400)
win.SetTitle("Grid Test")
win.Connect("destroy", func() { gtk.MainQuit() })
grid,_ := gtk.GridNew()
grid.SetOrientation(gtk.ORIENTATION_VERTICAL)
lbl,_:=gtk.LabelNew("Label 0")
grid.Attach(lbl,1,1,1,1)
lbl1,_:=gtk.LabelNew("Label 1")
grid.Attach(lbl1,1,2,1,1)
btn,_:=gtk.ButtonNewWithLabel("Click")
btn.Connect("clicked", func() {hdrClicked(grid,lbl)})
grid.Attach(btn,1,3,1,1)
win.Add(grid)
win.ShowAll()
gtk.Main()
}
func hdrClicked(grid *gtk.Grid, lblRef *gtk.Label){
fmt.Println("Click")
lbl,_:=gtk.LabelNew("Added Label")
grid.InsertRow(2)
grid.Attach(lbl,1,2,1,1)
grid.QueueDraw()
}

更多关于Golang中Gotk3 grid.InsertRow的问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
4 回复
我已修改原帖以反映此回复。
我已适当修改此回复,因为它已不再需要。
更多关于Golang中Gotk3 grid.InsertRow的问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
是的,我遗漏了一些东西。
lbl.Show() 必须被调用,因为 lbl 是在初始的 ShowAll() 调用之后创建的。
grid.QueueDraw() 没有效果,应该被删除。
如果我可以修改原帖中的代码,我会这样做。
以下是可运行的代码
package main
import ("github.com/gotk3/gotk3/gtk")
import "fmt"
func main(){
gtk.Init(nil)
major:=gtk.GetMajorVersion(); minor:=gtk.GetMinorVersion()
fmt.Println(fmt.Sprintf("GTK version %d.%d",major,minor))
win,_ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
win.SetDefaultSize(500,400)
win.SetTitle("Grid Test")
win.Connect("destroy", func() { gtk.MainQuit() })
grid,_ := gtk.GridNew()
grid.SetOrientation(gtk.ORIENTATION_VERTICAL)
lbl,_:=gtk.LabelNew("Label 0")
grid.Attach(lbl,1,1,1,1)
lbl1,_:=gtk.LabelNew("Label 1")
grid.Attach(lbl1,1,2,1,1)
btn,_:=gtk.ButtonNewWithLabel("Click")
btn.Connect("clicked", func() {hdrClicked(grid,lbl)})
grid.Attach(btn,1,3,1,1)
win.Add(grid)
win.ShowAll()
gtk.Main()
}
func hdrClicked(grid *gtk.Grid, lblRef *gtk.Label){
fmt.Println("Click")
lbl,_:=gtk.LabelNew("Added Label")
//grid.InsertNextTo(lblRef,gtk.POS_BOTTOM)
grid.InsertRow(2)
grid.Attach(lbl,1,2,1,1)
lbl.Show()
//grid.QueueDraw()
}
在Gotk3中使用grid.InsertRow()时需要注意插入位置和子控件重新附加的问题。你的代码中主要问题是插入行后没有正确重新定位现有控件。
以下是修正后的代码:
package main
import (
"fmt"
"github.com/gotk3/gotk3/gtk"
)
func main() {
gtk.Init(nil)
major := gtk.GetMajorVersion()
minor := gtk.GetMinorVersion()
fmt.Printf("GTK version %d.%d\n", major, minor)
win, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
win.SetDefaultSize(500, 400)
win.SetTitle("Grid Test")
win.Connect("destroy", func() { gtk.MainQuit() })
grid, _ := gtk.GridNew()
grid.SetOrientation(gtk.ORIENTATION_VERTICAL)
// 创建初始标签
lbl0, _ := gtk.LabelNew("Label 0")
grid.Attach(lbl0, 1, 0, 1, 1) // 第0行
lbl1, _ := gtk.LabelNew("Label 1")
grid.Attach(lbl1, 1, 1, 1, 1) // 第1行
btn, _ := gtk.ButtonNewWithLabel("Click to insert row")
btn.Connect("clicked", func() { hdrClicked(grid) })
grid.Attach(btn, 1, 2, 1, 1) // 第2行
win.Add(grid)
win.ShowAll()
gtk.Main()
}
func hdrClicked(grid *gtk.Grid) {
fmt.Println("Inserting row at position 2")
// 插入新行(在第2行位置插入)
grid.InsertRow(2)
// 创建新标签并附加到插入的行
newLbl, _ := gtk.LabelNew("Added Label")
grid.Attach(newLbl, 1, 2, 1, 1)
// 重新定位按钮到新行
// 首先需要获取按钮并重新附加
child := grid.GetChildAt(1, 3) // 按钮现在在第3行
if child != nil {
grid.Remove(child)
grid.Attach(child, 1, 3, 1, 1) // 重新附加到第3行
}
grid.QueueDraw()
grid.ShowAll()
}
或者使用更简洁的方法,在插入行时直接管理所有子控件的位置:
func hdrClicked(grid *gtk.Grid) {
fmt.Println("Inserting row at position 2")
// 保存需要移动的控件
var children []gtk.IWidget
// 获取第2行及之后的所有子控件
for i := 2; ; i++ {
child := grid.GetChildAt(1, i)
if child == nil {
break
}
children = append(children, child)
grid.Remove(child)
}
// 插入新行
grid.InsertRow(2)
// 添加新标签
newLbl, _ := gtk.LabelNew("Added Label")
grid.Attach(newLbl, 1, 2, 1, 1)
// 重新附加之前移除的控件(位置都下移一行)
for i, child := range children {
grid.Attach(child, 1, 3+i, 1, 1)
}
grid.QueueDraw()
grid.ShowAll()
}
关键点:
InsertRow()会在指定位置插入新行,该位置之后的行都会下移- 插入后需要重新管理现有控件的位置
- 使用
GetChildAt()获取特定位置的控件 - 调用
ShowAll()确保新添加的控件可见 - 行索引从0开始,注意不要越界

