Search code examples
pythongtkgtk3searchbar

Why won't my SearchEntry grow inside its SearchBar?


I have a Gtk.SearchBar with a Gtk.SearchEntry inside. I want the SearchEntry to use all the available (horizontal) space, so I set entry.props.hexpand = True and entry.props.halign = Gtk.Align.FILL. But for some reason the SearchBar won't grant it any extra space, and the Entry stays tiny.

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

window = Gtk.Window()
window.set_size_request(800, 300)

search_bar = Gtk.SearchBar()
search_bar.props.search_mode_enabled = True
search_bar.props.show_close_button = True
window.add(search_bar)

entry = Gtk.SearchEntry()
entry.props.hexpand = True
entry.props.halign = Gtk.Align.FILL
search_bar.add(entry)

window.show_all()
window.connect('destroy', Gtk.main_quit)
Gtk.main()

You can tell from the size and location of the close button that the SearchBar does use all the space in the Window. But the SearchEntry just won't grow larger than its standard size. Why is this and what can I do about it?


Solution

  • If you're looking for a simple solution, I have to apologize in advance for this answer. It's quite hacky, but it works. To start off, the SearchBar has a rather complicated child-widget setup. It looks like this:

    Gtk.SearchBar
    |   Gtk.Revealer
    |   |   Gtk.Box (we will call this "main_box")
    |   |   |   Gtk.Box (we will call this "box1")
    |   |   |   Gtk.Box (we will call this "box2")
    |   |   |   |   Gtk.SearchEntry
    |   |   |   Gtk.Box (we will call this "box3")
    |   |   |   |   Gtk.Button
    |   |   |   |   |    Gtk.Image
    

    The problem has it's root in a number of widgets here. Your solution is working, for the entry; the entry is expanding as far as it can. I'll explain the problems and their solutions, and then show the code at the end. The numbers are so that you can see which lines of code go with which solution steps.

    1. The entry's parent box, box2, is not expanding as far as it can. So, you need to set props.hexpand and props.halign for it as well. This partially works, but there's still some extra space on the left and right of the entry.

    2. To solve that, you need to remove box1 from main_box, since it doesn't need to be there. Now, the entry expands all the way to the left, but there's still some space between the right of the entry and the button.

    3. That is caused by box3 expanding when it shouldn't. So you need to set hexpand for box3 to False. This should fix the problem; your search bar's entry should expand the way you want it to, and the button should take up less horizontal space

    4. (optional) If you don't want the button to expand vertically, you can put the SearchBar in a VBox, and put that VBox in the window. Note that you need to call pack_start() on the VBox for this to work: vbox.pack_start(search_bar, False, False, 0).

    Here is the relevant code (Step 4 is omitted). You can add this code underneath the line search_bar.add(entry):

    # Get the correct children into the right variables
    main_box = search_bar.get_children()[0].get_children()[0]
    box1, box2, box3 = main_box.get_children()
    
    # Fix the problem
    box2.props.hexpand = True # See step 1
    box2.props.halign = Gtk.Align.FILL # See step 1
    main_box.remove(box1) # See step 2
    box3.props.hexpand = False # See step 3