Search code examples
pythonuser-interfacepygtkfilechooser

Customizing pygtk file chooser dialog


I am creating a Gtk file chooser dialog as follows (see below for full example):

dialog = Gtk.FileChooserDialog(
    title="Select a File",
    action=Gtk.FileChooserAction.OPEN)

I would also like to add a checkbox and dropdown combobox as extra widgets. Adding one extra widget works fine:

cb = Gtk.CheckButton("Only media files")
dialog.set_extra_widget(cb)

However, I would like to have a label and a combo box as well. I tried this:

cb = Gtk.CheckButton("Only media files")
dialog.set_extra_widget(cb)

db = Gtk.ComboBoxText()
db.append_text("Option 1")
db.append_text("Option 2")
db.set_active(0)
dialog.set_extra_widget(db)

However this only shows the combo box, not the check button. I thought maybe only one widget is allowed, so I created an hbox:

cb = Gtk.CheckButton("Only media files")
db = Gtk.ComboBoxText()
db.append_text("Option 1")
db.append_text("Option 2")
db.set_active(0)

hbox = Gtk.HBox(spacing=10)
hbox.pack_start(cb, False, False, 0)
hbox.pack_start(db, False, False, 0)

dialog.set_extra_widget(hbox)

Nope, nothing is shown. That doesn't work either. Then I read in the manual that "To pack widgets into a custom dialog, you should pack them into the Gtk.Box, available via Gtk.Dialog.get_content_area()." So I tried this:

    cb = Gtk.CheckButton("Only media files")
    db = Gtk.ComboBoxText()
    db.append_text("Option 1")
    db.append_text("Option 2")
    db.set_active(0)

    hbox = Gtk.HBox(spacing=10)
    hbox.pack_start(cb, False, False, 0)
    hbox.pack_start(db, False, False, 0)

    dbox = dialog.get_content_area()
    dbox.pack_start(hbox, False, False, 0)

Thus, my question is this: how can I add multiple custom widgets to the standard file chooser dialog from pygtk?

Here is a minimal reproducible (I hope) example. Just exchange the code between scisors with the fragments above if you want to test it.

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

def on_button_clicked(button):
    dialog = Gtk.FileChooserDialog(
        title="Select a File",
        action=Gtk.FileChooserAction.OPEN)

    # 8< -------------------
    cb = Gtk.CheckButton("Only media files")
    db = Gtk.ComboBoxText()
    db.append_text("Option 1")
    db.append_text("Option 2")
    db.set_active(0)

    hbox = Gtk.HBox(spacing=10)
    hbox.pack_start(cb, False, False, 0)
    hbox.pack_start(db, False, False, 0)

    dbox = dialog.get_content_area()
    dbox.pack_start(hbox, False, False, 0)
    # 8< -------------------

    response = dialog.run()

    dialog.destroy()

window = Gtk.Window()
window.set_default_size(300, 100)
window.connect("destroy", Gtk.main_quit)
button = Gtk.Button(label="Open FileChooserDialog")
button.connect("clicked", on_button_clicked)
window.add(button)
window.show_all()
Gtk.main()

Solution

  • It appears that solution #2 was the right way to go. However, I did not use the show_all method to actually show the widgets, which was the problem. With the following fragment the file chooser dialog with extra widgets works:

    cb = Gtk.CheckButton("Only media files")
    db = Gtk.ComboBoxText()
    db.append_text("Option 1")
    db.append_text("Option 2")
    db.set_active(0)
    
    hbox = Gtk.VBox(spacing=10)
    hbox.pack_start(cb, False, False, 0)
    hbox.pack_start(db, False, False, 0)
    hbox.show_all()
    
    dialog.set_extra_widget(hbox)