Gtk3 和 Python - 盒子不随窗口调整大小

2 投票
2 回答
2261 浏览
提问于 2025-04-18 14:44

我正在用Gtk3和Python写一个应用程序。我有一个侧边栏(叫做revealer)用来选择内容,还有一个webkit的网页视图用来显示主要内容。当这个侧边栏隐藏的时候,网页视图没有填满整个窗口的空间,我不知道为什么。希望能得到一些帮助。

from gi.repository import Gtk, Gio
from gi.repository import WebKit

HEIGHT = 500
WIDTH = 800

class MainWindow(Gtk.Window):

    def __init__(self):

        Gtk.Window.__init__(self, title="Resolution")
        self.set_border_width(0)
        self.set_default_size(WIDTH, HEIGHT)

        hb = Gtk.HeaderBar()
        hb.props.show_close_button = True
        hb.props.title = "Resolution"
        self.set_titlebar(hb)

        button = Gtk.Button()   
        icon = Gio.ThemedIcon(name="emblem-system-symbolic")
        image = Gtk.Image.new_from_gicon(icon, 1)
        button.add(image)
        button.connect("clicked", self.sidebarShowHide)
        button.set_focus_on_click(False)
        hb.pack_start(button)  

        sidebarbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
        toplevelbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)

        self.add(toplevelbox)

        self.sidebar = Gtk.Revealer()
        self.sidebar.set_transition_duration(0)
        self.sidebar.set_reveal_child(False)
        toplevelbox.pack_start(self.sidebar, False, False, 0)
        self.sidebar.add(sidebarbox)

        self.searchentry = Gtk.SearchEntry()
        self.searchentry.connect("search-changed", self.search_changed)
        sidebarbox.pack_start(self.searchentry, False, False, 0)

        label = Gtk.Label("Contents Selector")
        sidebarbox.pack_start(label, True, True, 0)

        scroller = Gtk.ScrolledWindow()
        content = WebKit.WebView()
        scroller.add(content)
        toplevelbox.pack_start(scroller, True, True, 0)

        content.open("/home/oliver/resolution/placeholder.html")

    def sidebarShowHide(self, button):
        if self.sidebar.get_reveal_child():
            self.sidebar.set_reveal_child(False)
        else:
            self.sidebar.set_reveal_child(True)

    def search_changed(self, searchentry):
        pass




win = MainWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

2 个回答

0

这听起来像是个 bug。

作为一个临时解决办法,你可以使用

def sidebarShowHide(self, button):
    self.sidebarbox.set_visible(not self.sidebarbox.get_visible())

不过这样做不会有任何过渡动画,只是暂时把它的占用空间去掉了。


其实在 git 仓库里提供的 C 示例是按预期大小调整的,所以这可能和子控件的首选方向有关。

1

几个月前,我做过一些关于GtkRevealer的事情,它是可以工作的。看到这段代码不工作让我很烦。

我重新打开了我的项目,查看那部分代码,结果发现Gtk.Revealer所在的顶层容器必须设置为Gtk.Orientation.VERTICAL。如果你把“toplevelbox”的方向改成这个,它就能正常工作了,不过这样的话就不是侧边栏了,而是从顶部或底部出现。如果你把GtkBox换成GtkGrid也是一样的。如果我猜的话,这可能和子元素的默认方向有关。

解决这个问题的方法是使用小部件的隐藏/显示机制(相信我,我仔细研究过你的代码,它是有效的)。

from gi.repository import Gtk, Gio
from gi.repository import WebKit

HEIGHT = 500
WIDTH = 800

class MainWindow(Gtk.Window):

 def __init__(self):

    Gtk.Window.__init__(self, title="Resolution")
    self.set_border_width(0)
    self.set_default_size(WIDTH, HEIGHT)

    hb = Gtk.HeaderBar()
    hb.props.show_close_button = True
    hb.props.title = "Resolution"
    self.set_titlebar(hb)

    button = Gtk.Button()   
    icon = Gio.ThemedIcon(name="emblem-system-symbolic")
    image = Gtk.Image.new_from_gicon(icon, 1)
    button.add(image)
    button.connect("clicked", self.sidebarShowHide)
    button.set_focus_on_click(False)
    hb.pack_start(button)  

    sidebarbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
    toplevelbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)

    self.add(toplevelbox)

    self.sidebar = Gtk.Box()     
    toplevelbox.pack_start(self.sidebar, False, False, 0)
    self.sidebar.add(sidebarbox)

    self.searchentry = Gtk.SearchEntry()
    self.searchentry.connect("search-changed", self.search_changed)
    sidebarbox.pack_start(self.searchentry, False, False, 0)

    label = Gtk.Label("Contents Selector")
    sidebarbox.pack_start(label, True, True, 0)

    scroller = Gtk.ScrolledWindow()
    content = WebKit.WebView()
    scroller.add(content)
    toplevelbox.pack_start(scroller, True, True, 0)

    content.open("/home/oliver/resolution/placeholder.html")

def sidebarShowHide(self, button):
    if self.sidebar.get_visible():
        self.sidebar.hide ()
    else:
        self.sidebar.show ()

def search_changed(self, searchentry):
    pass




win = MainWindow()
win.connect("delete-event", Gtk.main_quit)  
win.show_all()
Gtk.main()

撰写回答