FileChooserDialog (Python) Marta Maria Casetti mmcasetti@gmail.com 2012 Dialogové okno vhodné pro příkazy „Otevřít“ a „Uložit“ FileChooserDialog

Tento FileChooserDialog ukládá textové dokumenty, které mohou být otevřeny nebo napsány od nuly v TextView (viz dále).

Je také možné zavolat FileChooserDialog pro otevření nového dokumentu.

Kroky k reprodukci příkladu

Vytvořte soubor .ui, který bude popisovat aplikační nabídku s položkami „New“, „Open“, „Save“, „Save As“ a „Quit“. To můžete udělat v Glade nebo v textovém editoru. Viz .

Vytvořte program v jazyce Python pro Gtk.TextView s Gtk.Buffer self.buffer a self.file, což bude Gio.File nastavený na počátku na None.

V tomto programu vytvoříme také akce odpovídající položkám v aplikační nabídce, napojíme je na funkce zpětného volání a naimportujeme nabídku pomocí metody do_startup() třídy Gtk.Builder.

Akce New a Quit a jejich funkce zpětného volání jsou velmi jednoduché, viz . Podrobnější vysvětlení signálů a funkcí zpětného volání najdete v .

Zpětné volání akce Open by mělo vytvořit a otevřít Gtk.FileChooserDialog pro otevření souboru. Toto dialogové okno je napojeno na jiné funkce zpětného volání, jednu pro tlačítko Open a druhou pro tlačítko Cancel dialogového okna.

Akce Save as funguje podobně jako Open, akorát funkce zpětného volání pro tlačítko Save závisí na mnohem komplexnější metodě save_to_file().

Akci Save lze zúžit na případ, kdy soubor je None, což je případ, kdy self.file je nový soubor, a tím pádem to změníme na akci Save as, a případ, kdy soubor není None, což se zúží na save_to_file().

A nakonec metoda save_to_file(): viz , řádky 146 – 175.

Soubor XML, který vytváří nabídku aplikace <?xml version="1.0"?> <interface> <menu id="appmenu"> <section> <item> <attribute name="label">New</attribute> <attribute name="action">win.new</attribute> </item> <item> <attribute name="label">Open</attribute> <attribute name="action">win.open</attribute> </item> </section> <section> <item> <attribute name="label">Save</attribute> <attribute name="action">win.save</attribute> </item> <item> <attribute name="label">Save As...</attribute> <attribute name="action">win.save-as</attribute> </item> </section> <section> <item> <attribute name="label">Quit</attribute> <attribute name="action">app.quit</attribute> </item> </section> </menu> </interface>
Kód použitý k vygenerování tohoto příkladu from gi.repository import Gtk from gi.repository import Gdk from gi.repository import Gio from gi.repository import GObject import sys class MyWindow(Gtk.ApplicationWindow): def __init__(self, app): Gtk.Window.__init__( self, title="FileChooserDialog Example", application=app) self.set_default_size(400, 400) # Akce pro nabídku okna, napojí se na funkci zpětného volání new_action = Gio.SimpleAction.new("new", None) new_action.connect("activate", self.new_callback) self.add_action(new_action) open_action = Gio.SimpleAction.new("open", None) open_action.connect("activate", self.open_callback) self.add_action(open_action) save_action = Gio.SimpleAction.new("save", None) save_action.connect("activate", self.save_callback) self.add_action(save_action) save_as_action = Gio.SimpleAction.new("save-as", None) save_as_action.connect("activate", self.save_as_callback) self.add_action(save_as_action) # Soubor self.file = None # TextView s vyrovnávací pamětí self.buffer = Gtk.TextBuffer() textview = Gtk.TextView(buffer=self.buffer) textview.set_wrap_mode(Gtk.WrapMode.WORD) # Okno s posuvníky pro TextView self.scrolled_window = Gtk.ScrolledWindow() self.scrolled_window.set_policy( Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) self.scrolled_window.add(textview) self.scrolled_window.set_border_width(5) # Přidá okno s posuvníky do okna self.add(self.scrolled_window) # Zpětné volání pro "new" def new_callback(self, action, parameter): self.buffer.set_text("") print("New file created") # Zpětné volání pro "open" def open_callback(self, action, parameter): # Vytvoří FileChooserDialog pro otevření # argumenty jsou: název okna, rodičovské okno, akce, # (tlačítka, odpověď) open_dialog = Gtk.FileChooserDialog("Pick a file", self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT)) # Lze vybírat nejen místní soubory open_dialog.set_local_only(False) # Dialogové okno bude vždy nad oknem s TextView open_dialog.set_modal(True) # Napojí dialogové okno na funci zpětného volání open_response_cb() open_dialog.connect("response", self.open_response_cb) # Zobrazí dialogové okno open_dialog.show() # Funkce zpětného volání pro dialogové okno open_dialog def open_response_cb(self, dialog, response_id): open_dialog = dialog # Pokud odpověď je "ACCEPT" (bylo kliknuto na tlačítko "Open") if response_id == Gtk.ResponseType.ACCEPT: # self.file je soubor, který jsme od FileChooserDialog dostali self.file = open_dialog.get_file() # Prázdný řetězec (prozatímně) content = "" try: # Načte obsah souboru do paměti # success: pravdivostní hodnota závisející na úspěchu operace # content: obsah # etags: je značka entity (může být použit k rychlému určení, jestli # byl soubor změněn vůči verzi v souborovém systému) [success, content, etags] = self.file.load_contents(None) except GObject.GError as e: print("Error: " + e.message) # Nastaví obsah jako text do vyrovnávací paměti self.buffer.set_text(content, len(content)) print("opened: " + open_dialog.get_filename()) # Pokud odpověď je "CANCEL" (vylo kliknuto na tlačítko "Cancel") elif response_id == Gtk.ResponseType.CANCEL: print("cancelled: FileChooserAction.OPEN") # Zlikviduje FileChooserDialog dialog.destroy() # Funkce zpětného volání pro "save_as" def save_as_callback(self, action, parameter): # Vytvoří FileChooserDialog pro uložení # argumenty jsou: název okna, rodičovské okno, akce, # (tlačítka, odpověď) save_dialog = Gtk.FileChooserDialog("Pick a file", self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.ACCEPT)) # Pokud uživatel zadá název souboru, který již existuje, zobrazí dialogové okno # dotaz na potvrzení save_dialog.set_do_overwrite_confirmation(True) # Dialogové okno bude vždy nad oknem s TextView save_dialog.set_modal(True) # Pokud byl self.file již uložen if self.file is not None: try: # Nastaví self.file jako aktuální název do výběru souboru save_dialog.set_file(self.file) except GObject.GError as e: print("Error: " + e.message) # Napojí dialogové okno na funkci zpětného volání save_response_cb() save_dialog.connect("response", self.save_response_cb) # Zobrazí dialogové okno save_dialog.show() # Funkce zpětného volání pro dialogové okno save_dialog def save_response_cb(self, dialog, response_id): save_dialog = dialog # Pokud odpověď je "ACCEPT" (bylo kliknuto na tlačítko "Save") if response_id == Gtk.ResponseType.ACCEPT: # self.file je aktuálně vybraný soubor self.file = save_dialog.get_file() # Uloží do souboru (viz níže) self.save_to_file() # Pokud odpověď je "CANCEL" (bylo kliknuto na tlačítko "Cancel") elif response_id == Gtk.ResponseType.CANCEL: print("cancelled: FileChooserAction.SAVE") # Zlikviduje FileChooserDialog dialog.destroy() # Funkce zpětného volání pro uložení def save_callback(self, action, parameter): # Pokud tam self.file zatím není if self.file is not None: self.save_to_file() # self.file je nový soubor else: # Použije save_as self.save_as_callback(action, parameter) # Uložení do souboru def save_to_file(self): # Získá obsah vyrovnávací paměti, bez skrytých znaků [start, end] = self.buffer.get_bounds() current_contents = self.buffer.get_text(start, end, False) # Pokud je nějaký obsah if current_contents != "": # Nastaví obsah jako obsah souboru self.file # argumenty: obsah, značka entity, vytvořit zálohu?, příznaky, GError try: self.file.replace_contents(current_contents, None, False, Gio.FileCreateFlags.NONE, None) print("saved: " + self.file.get_path()) except GObject.GError as e: print("Error: " + e.message) # Pokud je obsah prázdný else: # Vytvoří (když soubor neexistuje) nebo přepíše soubor v režimu zápisu # argumenty: značka entity, vytvořit zálohu?, příznaky, GError try: self.file.replace_readwrite(None, False, Gio.FileCreateFlags.NONE, None) print("saved: " + self.file.get_path()) except GObject.GError as e: print("Error: " + e.message) class MyApplication(Gtk.Application): def __init__(self): Gtk.Application.__init__(self) def do_activate(self): win = MyWindow(self) win.show_all() def do_startup(self): Gtk.Application.do_startup(self) # Akce "quit" aplikace, napojí se na funkci zpětného volání quit_action = Gio.SimpleAction.new("quit", None) quit_action.connect("activate", self.quit_callback) self.add_action(quit_action) # Získá nabídku ze souboru s UI pomocí Builderu builder = Gtk.Builder() try: builder.add_from_file("filechooserdialog.ui") except: print("file not found") sys.exit() menu = builder.get_object("appmenu") self.set_app_menu(menu) # Funkce zpětného volání pro "quit" def quit_callback(self, action, parameter): self.quit() app = MyApplication() exit_status = app.run(sys.argv) sys.exit(exit_status)
Užitečné metody pro FileChooserDialog

Poznamenejme, že akce u dialogového okna pro výběr souboru může být některá z následujících: Gtk.FileChooserAction.OPEN (umožní uživateli jen vybrat existující soubor) Gtk.FileChooserAction.SAVE (umožní uživateli vybrat existující soubor nebo napsat název nového), Gtk.FileChooserAction.SELECT_FOLDER (umožní uživateli jen vybrat existující složku), Gtk.FileChooserAction.CREATE_FOLDER (umožní uživateli vybrat existující složku nebo napsat název nové).

Mimo metod použitých v , máme:

set_show_hidden(True) se používá k zobrazení skrytých souborů a složek.

set_select_multiple(True) nastavuje možnost vybrat více souborů naráz. To má význam jen v případě, že režim je Gtk.FileChooserAction.OPEN nebo Gtk.FileChooserAction.SELECT_FOLDER.

V dialogovém okně Uložení jako funkce set_current_name(aktuální_název) nastavuje ve výběru souboru aktuální_název, jako by jej zadal uživatel. aktuální_název může být něco jako Untitled.txt. Tato metoda by se neměla používat jinde než pro „Uložit jako“.

Výchozí aktuální složkou jsou nedávné položky. Pro nastavení jiné složky použijte set_current_folder_uri(uri). Upozorňujeme ale, že tuto metodu byste měli použít, a přimět tím výběr souboru zobrazit zadanou složku, jen když provádíte „Uložit jako“ a máte již soubor někde uložený.

Odkazy k API

V této ukázce se používá následující:

GtkFileChooserDialog

GtkFileChooser

GtkWindow

GtkTextView

GtkTextBuffer

GtkScrolledWindow

GFile

GSimpleAction

GtkBuilder