首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动滚动gtkscrolledwindow窗口

自动滚动gtkscrolledwindow窗口
EN

Stack Overflow用户
提问于 2011-08-02 03:12:53
回答 3查看 3.3K关注 0票数 3

我有一个表单界面,其中包含大量的水平下拉框和GTKscrolledWindow中的文本框。表单必须水平对齐,因为窗口中有无限数量的表单(想想表单的标签)。

当操作员按tabs键切换到屏幕右侧的下一个表单控件时,是否(可能/如何操作)自动向右滚动GTKScrolledWindow。?

相关的问题是我如何检测被聚焦的元素(按钮等)在它的父滚动窗口中是否可见。

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-18 23:03:47

这是我根据Michy的回答所做的。

要使滚动窗口自动滚动,请在构造函数中运行:

代码语言:javascript
复制
FocusScroll(scrolledwindow).

    class FocusScroll(object):
    """
    Get a gtk.ScrolledWindow which contains a gtk.Viewport.
    Attach event handlers which will scroll it to show the focused widget.
    """
    def __init__(self, scrolledwindow):
        self.scrolledwindow = scrolledwindow
        self.viewport = scrolledwindow.get_child()
        assert isinstance(self.viewport, gtk.Viewport)
        self.main_widget = self.viewport.get_child()
        self.vadj = scrolledwindow.get_vadjustment()
        self.window = self.get_window(scrolledwindow)

        self.viewport.connect('set-focus-child', self.on_viewport_set_focus_child)

    def get_window(self, widget):
        if isinstance(widget, gtk.Window):
            return widget
        else:
            return self.get_window(widget.get_parent())

    def is_child(self, widget, container):
        """
        Go recursively over all children of container, to check if widget is
        a child of it.
        """
        for child in container.get_children():
            if child is widget:
                return True
            elif isinstance(child, gtk.Container):
                if self.is_child(widget, child):
                    return True
        else:
            return False

    def on_viewport_set_focus_child(self, _viewport, _child):
        idle_add(self.scroll_slide_viewport)

    def scroll_slide_viewport(self):
        """Scroll the viewport if needed to see the current focused widget"""
        widget = self.window.get_focus()
        if not self.is_child(widget, self.main_widget):
            return

        _wleft, wtop = widget.translate_coordinates(self.main_widget, 0, 0)
        wbottom = wtop + widget.get_allocation().height

        top = self.vadj.value
        bottom = top + self.vadj.page_size

        if wtop < top:
            self.vadj.value = wtop
        elif wbottom > bottom:
            self.vadj.value = wbottom - self.vadj.page_size
票数 2
EN

Stack Overflow用户

发布于 2011-08-02 20:37:08

我希望你不介意我在描述中使用GTK+ C应用编程接口,解决方案可以很容易地转换为PyGTK,并且原理保持不变。

从第二个问题开始-如果您知道要测试哪个小部件,则可以通过调用gtk_widget_translate_coordinates(child, parent, 0, 0, &x, &y)来获取子部件相对于父部件的位置,从而检测其可见性。通过gtk_widget_get_allocation(),你可以得到父元素和子元素的大小,然后你可以简单地测试整个子元素矩形是否在滚动窗口中。

代码语言:javascript
复制
gboolean is_visible_in (GtkWidget *child, GtkWidget *scrolled)
{
    gint x, y;
    GtkAllocation child_alloc, scroll_alloc;
    gtk_widget_translate_coordinates (child, scrolled, 0, 0, &x, &y);
    gtk_widget_get_allocation(child, &child_alloc);
    gtk_widget_get_allocation(scrolled, &scroll_alloc);

    return (x >= 0 && y >= 0) 
        && x + child_alloc.width <= scroll_alloc.width
        && y + child_alloc.height <= scroll_alloc.height;
}

您可以通过gtk_window_get_focus ()在窗口中获取当前聚焦的小部件,也可以在焦点发生变化时检测到它。

在自动滚动问题中,您可以处理连接到可以聚焦的小部件的"focus"信号,也可以处理连接到包含小部件的容器的"set-focus-child"事件。在信号处理程序中,您应该检查聚焦的小部件是否可见。如果没有,请确定其位置并正确滚动。

为此,您必须检测小部件在整个滚动区域内的位置。如果你正在使用一些不支持滚动的容器(如GtkHBox),在GtkScrolledWindow (视窗调整)中,你可以再次通过gtk_widget_translate_coordinates()获得聚焦的控件相对于容器的坐标-现在使用容器而不是滚动的窗口。调整的值,如果使用GtkViewport,则调整值对应于滚动区域中以像素为单位的位置,因此将调整值设置为x相对坐标将进行滚动。因此,处理程序的重要部分可能是

代码语言:javascript
复制
    GtkWidget *scrolled = /* The scrolled window */
    GtkWidget *container = /* The container in the scrolled window */
    GtkWidget *focused = /* The focused widget */

    GtkAdjustment *hadj = gtk_scrolled_window_get_hadjustment( 
        GTK_SCROLLED_WINDOW(scrolled));
    gint x, y;
    gtk_widget_translate_coordinates (focused, container, 0, 0, &x, &y);
    gtk_adjustment_set_value(hadj, min(x, maximal adjustment value allowed);

允许的最大调整值为adjustment.upper - adjustment.page_size。聚焦的小部件作为两个信号的信号处理程序参数传递,在"set-focus-child"信号的情况下,还将容器作为参数传递。

票数 4
EN

Stack Overflow用户

发布于 2011-08-02 20:17:39

第一,第一个。你是如何检测焦点的?连接到GtkWidget::focus信号。在回调中,你可以将窗口滚动到你喜欢的任何地方,如何做到这一点,你需要获得GtkScrolledWindow的GtkAdjustment,并相应地移动它来显示你想要的东西。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6903170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档