滚动到 GtkListBox 中的选定行

我在这里有点没有想法。我想要一件非常简单的事情:能够以GtkListBox编程方式选择给定的行,然后滚动列表框(包含在 aScrolledWindow和 a中Viewport)。

选择一行是微不足道的(我的代码是 Go & gotk3,但这不是那么重要):

listBox.SelectRow(row)

但是滚动到该行被证明是一个真正的挑战。无论我尝试什么,我都失败了:

  • 我试图集中这一行,但没有任何帮助

  • 我试图用 来计算行的 Y 坐标gtk_widget_translate_coordinates(),但它对任何行都返回 -1

  • 也许我可以找出列表框顶部和底部的哪一行,并用它来滚动,ScrolledWindow但我不知道该怎么做。

更新:我已经尝试过这里的建议:手动滚动到 Gtk.ScrolledWindow 中的孩子,但它没有工作,因为仍然没有滚动发生:

listbox.SelectRow(rowToSelect)

listbox.SetFocusVAdjustment(listbox.GetAdjustment())

if rowToSelect != nil {

    rowToSelect.GrabFocus()

}

我也使用下面的代码对 's child 进行了同样的尝试rowToSelect,但无济于事:


if c, err := rowToSelect.GetChild(); err == nil {

    c.GrabFocus()

}


幕布斯7119047
浏览 189回答 2
2回答

胡子哥哥

感谢 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()而不是在填充列表框的代码中调用。

神不在的星期二

所以,我有同样的问题,但设法让它在我的情况下工作。我认为我的解决方案也很有可能对您有用。由于该grab_focus方法不起作用,我开始使用listbox_get_row_at_y. 非常不满意,但希望它会奏效。而且..它没有用,因为get_row_at_y总是返回null,对于我提供的所有 y 值。而且我知道列表框不是空的。所以这让我意识到我正在尝试集中我刚刚添加到列表框中的一行。该行还没有实现,它无法集中,因为它还没有准备好。所以我更改了我的代码来填充列表框,等待 100 毫秒 timeout,然后才调用grab_focus. 那行得通!我实际上正在使用一个为我包装超时调用的库,但我认为您可以为此目的在“原始”gtk 中使用g_timeout_add 。请注意,这意味着调用grab_focus已经预先填充的列表框并且在屏幕上实现的项目应该直接工作。如果这是你的情况,那么这对你没有帮助。
打开App,查看更多内容
随时随地看视频慕课网APP