2 回答
TA贡献1825条经验 获得超6个赞
感谢 Emmanuel Touzery 的提示,我终于搞定了。我不必使用计时器,但问题确实是在填充列表框的那一刻,该行尚未实现,因此不可能发生坐标转换。
我所做的是使用 GLib's 安排滚动idle_add(),这使它在下游发生,这似乎工作得很好:有关详细信息,请参阅此提交。
简而言之,这一切都归结为以下代码:
func ListBoxScrollToSelected(listBox *gtk.ListBox) {
// If there's selection
if row := listBox.GetSelectedRow(); row != nil {
// Convert the row's Y coordinate into the list box's coordinate
if _, y, _ := row.TranslateCoordinates(listBox, 0, 0); y >= 0 {
// Scroll the vertical adjustment to center the row in the viewport
if adj := listBox.GetAdjustment(); adj != nil {
_, rowHeight := row.GetPreferredHeight()
adj.SetValue(float64(y) - (adj.GetPageSize()-float64(rowHeight))/2)
}
}
}
}
上面的函数必须使用glib.IdleAdd()而不是在填充列表框的代码中调用。
TA贡献1963条经验 获得超6个赞
所以,我有同样的问题,但设法让它在我的情况下工作。我认为我的解决方案也很有可能对您有用。
由于该grab_focus
方法不起作用,我开始使用listbox_get_row_at_y
. 非常不满意,但希望它会奏效。而且..它没有用,因为get_row_at_y
总是返回null
,对于我提供的所有 y 值。而且我知道列表框不是空的。所以这让我意识到我正在尝试集中我刚刚添加到列表框中的一行。该行还没有实现,它无法集中,因为它还没有准备好。
所以我更改了我的代码来填充列表框,等待 100 毫秒 timeout,然后才调用grab_focus
. 那行得通!
我实际上正在使用一个为我包装超时调用的库,但我认为您可以为此目的在“原始”gtk 中使用g_timeout_add 。
请注意,这意味着调用grab_focus
已经预先填充的列表框并且在屏幕上实现的项目应该直接工作。如果这是你的情况,那么这对你没有帮助。
- 2 回答
- 0 关注
- 214 浏览
添加回答
举报