<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2001/XInclude" type="guide" style="task" id="filechooserdialog.py" xml:lang="cs">
<info>
<title type="text">FileChooserDialog (Python)</title>
<link type="guide" xref="beginner.py#file-selectors"/>
<link type="seealso" xref="gmenu.py"/>
<link type="seealso" xref="toolbar_builder.py"/>
<link type="seealso" xref="textview.py"/>
<link type="next" xref="combobox.py"/>
<revision version="0.1" date="2012-08-14" status="draft"/>
<credit type="author copyright">
<name>Marta Maria Casetti</name>
<email its:translate="no">mmcasetti@gmail.com</email>
<years>2012</years>
</credit>
<desc>Dialogové okno vhodné pro příkazy „Otevřít“ a „Uložit“</desc>
</info>
<title>FileChooserDialog</title>
<media type="image" mime="image/png" src="media/filechooserdialog_save.png"/>
<p>Tento FileChooserDialog ukládá textové dokumenty, které mohou být otevřeny nebo napsány od nuly v TextView (viz dále).</p>
<media type="image" mime="image/png" src="media/filechooserdialog_menu.png"/>
<p>Je také možné zavolat FileChooserDialog pro otevření nového dokumentu.</p>
<links type="sections"/>
<section id="overview">
<title>Kroky k reprodukci příkladu</title>
<steps>
<item><p>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 <link xref="#xml"/>.</p></item>
<item><p>Vytvořte program v jazyce Python pro Gtk.TextView s Gtk.Buffer <code>self.buffer</code> a <code>self.file</code>, což bude Gio.File nastavený na počátku na <code>None</code>.</p></item>
<item><p>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 <code>do_startup()</code> třídy <code>Gtk.Builder</code>.</p></item>
<item><p>Akce <gui>New</gui> a <gui>Quit</gui> a jejich funkce zpětného volání jsou velmi jednoduché, viz <link xref="#code"/>. Podrobnější vysvětlení signálů a funkcí zpětného volání najdete v <link xref="signals-callbacks.py"/>.</p></item>
<item><p>Zpětné volání akce <gui>Open</gui> by mělo vytvořit a otevřít <code>Gtk.FileChooserDialog</code> pro otevření souboru. Toto dialogové okno je napojeno na jiné funkce zpětného volání, jednu pro tlačítko <gui>Open</gui> a druhou pro tlačítko <gui>Cancel</gui> dialogového okna.</p></item>
<item><p>Akce <gui>Save as</gui> funguje podobně jako <gui>Open</gui>, akorát funkce zpětného volání pro tlačítko <gui>Save</gui> závisí na mnohem komplexnější metodě <code>save_to_file()</code>.</p></item>
<item><p>Akci <gui>Save</gui> lze zúžit na případ, kdy soubor je <code>None</code>, což je případ, kdy <code>self.file</code> je nový soubor, a tím pádem to změníme na akci <gui>Save as</gui>, a případ, kdy soubor není <code>None</code>, což se zúží na <code>save_to_file()</code>.</p></item>
<item><p>A nakonec metoda <code>save_to_file()</code>: viz <link xref="#code"/>, řádky 146 – 175.</p></item>
</steps>
</section>
<section id="xml">
<title>Soubor XML, který vytváří nabídku aplikace</title>
<code mime="application/xml" style="numbered"><?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>
</code>
</section>
<section id="code">
<title>Kód použitý k vygenerování tohoto příkladu</title>
<code mime="text/x-python" style="numbered">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)
</code>
</section>
<section id="methods">
<title>Užitečné metody pro FileChooserDialog</title>
<p>Poznamenejme, že akce u dialogového okna pro výběr souboru může být některá z následujících: <code>Gtk.FileChooserAction.OPEN</code> (umožní uživateli jen vybrat existující soubor) <code>Gtk.FileChooserAction.SAVE</code> (umožní uživateli vybrat existující soubor nebo napsat název nového), <code>Gtk.FileChooserAction.SELECT_FOLDER</code> (umožní uživateli jen vybrat existující složku), <code>Gtk.FileChooserAction.CREATE_FOLDER</code> (umožní uživateli vybrat existující složku nebo napsat název nové).</p>
<p>Mimo metod použitých v <link xref="#code"/>, máme:</p>
<list>
<item><p><code>set_show_hidden(True)</code> se používá k zobrazení skrytých souborů a složek.</p></item>
<item><p><code>set_select_multiple(True)</code> nastavuje možnost vybrat více souborů naráz. To má význam jen v případě, že režim je <code>Gtk.FileChooserAction.OPEN</code> nebo <code>Gtk.FileChooserAction.SELECT_FOLDER</code>.</p></item>
<item><p>V dialogovém okně <gui>Uložení jako</gui> funkce <code>set_current_name(aktuální_název)</code> nastavuje ve výběru souboru <code>aktuální_název</code>, jako by jej zadal uživatel. <code>aktuální_název</code> může být něco jako <em>Untitled.txt</em>. Tato metoda by se neměla používat jinde než pro „Uložit jako“.</p></item>
<item><p>Výchozí aktuální složkou jsou nedávné položky. Pro nastavení jiné složky použijte <code>set_current_folder_uri(uri)</code>. 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ý.</p></item>
</list>
</section>
<section id="references">
<title>Odkazy k API</title>
<p>V této ukázce se používá následující:</p>
<list>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkFileChooserDialog.html">GtkFileChooserDialog</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkFileChooser.html">GtkFileChooser</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkWindow.html">GtkWindow</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkTextView.html">GtkTextView</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkTextBuffer.html">GtkTextBuffer</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkScrolledWindow.html">GtkScrolledWindow</link></p></item>
<item><p><link href="http://developer.gnome.org/gio/stable/GFile.html">GFile</link></p></item>
<item><p><link href="http://developer.gnome.org/gio/stable/GSimpleAction.html">GSimpleAction</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkBuilder.html">GtkBuilder</link></p></item>
</list>
</section>
</page>