<?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="ko">
<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>"열기" 및 "저장" 명령에 알맞은 대화상자</desc>
<mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
<mal:name>조성호</mal:name>
<mal:email>shcho@gnome.org</mal:email>
<mal:years>2017</mal:years>
</mal:credit>
</info>
<title>FileChooserDialog</title>
<media type="image" mime="image/png" src="media/filechooserdialog_save.png"/>
<p>FileChooserDialog는 TextView에 열었거나 바닥부터 새로 작성한 텍스트 문서를 저장합니다(하단 참고).</p>
<media type="image" mime="image/png" src="media/filechooserdialog_menu.png"/>
<p>새 문서를 열 때 FileChooserDialog를 호출할 수 있습니다.</p>
<links type="sections"/>
<section id="overview">
<title>예제를 다시 만드는 과정</title>
<steps>
<item><p>"New", "Open", "Save", "Save as", "Quit" 항목이 들어간 app-menu 설명 .ui 파일을 만드십시오. 글레이드 개발 환경이나 텍스트 편집기에서 처리할 수 있습니다. <link xref="#xml"/> 내용을 참고하십시오.</p></item>
<item><p>Gtk.TextViewGtk.Buffer <code>self.buffer</code>와 <code>None</code>으로 초기값을 설정한 Gio.File 형식의 <code>self.file</code> 로 Gtk.TextView 파이썬 프로그램을 만드십시오.</p></item>
<item><p>이 프로그램에서 app-menu에 항목마다 관련 동작을 만드시고, 콜백 함수에 연결하신 다음, Gtk.Builder의 <code>do_startup()</code> 메서드로 메뉴를 가져오십시오.</p></item>
<item><p>"새 파일" 및 "끝내기" 동작과 콜백 함수는 조금 단순합니다. <link xref="#code"/>를 참고해보시죠. 시그널 및 콜백 함수에 대한 자세한 설명은 <link xref="signals-callbacks.py"/>를 살펴보십시오.</p></item>
<item><p>"열기" 콜백 함수에서는 "열기" 동작에 맞게 Gtk.FileChooserDialog를 만들고 연 다음, FileChooserDialog의 "열기" 및 "취소" 단추에 제각기 다른 콜백 함수를 연결해야합니다.</p></item>
<item><p>"다른 이름으로 저장"은 "열기"와 근본적으로 비슷하게 동작하지만, "저장" 단추의 콜백 함수 동작은 좀 더 복잡한 메서드 <code>save_to_file()</code>에 따릅니다.</p></item>
<item><p>"저장" 동작은, <code>self.file</code> 이 새 파일이어서 파일이 <code>None</code>(없음)일 경우로 경우의 수를 줄일 수 있으며, 이때는 "다른 이름으로 저장"인 경우로 되돌릴 수 있습니다. 그리고 파일이 <code>None</code>(없음) 상태가 아닐 경우, <code>save_to_file()</code> 호출만으로 과정을 줄입니다.</p></item>
<item><p>마지막으로, <code>save_to_file()</code> 메서드는 <link xref="#code"/> 146번째 줄부터 175번째 줄 까지의 부분을 참고하십시오.</p></item>
</steps>
</section>
<section id="xml">
<title>app-menu를 만드는 XML 파일</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>예제 결과를 만드는 코드</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)
# the actions for the window menu, connected to the callback functions
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)
# the file
self.file = None
# the textview with the buffer
self.buffer = Gtk.TextBuffer()
textview = Gtk.TextView(buffer=self.buffer)
textview.set_wrap_mode(Gtk.WrapMode.WORD)
# a scrolled window for the 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)
# add the scrolled window to the window
self.add(self.scrolled_window)
# callback for new
def new_callback(self, action, parameter):
self.buffer.set_text("")
print("New file created")
# callback for open
def open_callback(self, action, parameter):
# create a filechooserdialog to open:
# the arguments are: title of the window, parent_window, action,
# (buttons, response)
open_dialog = Gtk.FileChooserDialog("Pick a file", self,
Gtk.FileChooserAction.OPEN,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT))
# not only local files can be selected in the file selector
open_dialog.set_local_only(False)
# dialog always on top of the textview window
open_dialog.set_modal(True)
# connect the dialog with the callback function open_response_cb()
open_dialog.connect("response", self.open_response_cb)
# show the dialog
open_dialog.show()
# callback function for the dialog open_dialog
def open_response_cb(self, dialog, response_id):
open_dialog = dialog
# if response is "ACCEPT" (the button "Open" has been clicked)
if response_id == Gtk.ResponseType.ACCEPT:
# self.file is the file that we get from the FileChooserDialog
self.file = open_dialog.get_file()
# an empty string (provisionally)
content = ""
try:
# load the content of the file into memory:
# success is a boolean depending on the success of the operation
# content is self-explanatory
# etags is an entity tag (can be used to quickly determine if the
# file has been modified from the version on the file system)
[success, content, etags] = self.file.load_contents(None)
except GObject.GError as e:
print("Error: " + e.message)
# set the content as the text into the buffer
self.buffer.set_text(content, len(content))
print("opened: " + open_dialog.get_filename())
# if response is "CANCEL" (the button "Cancel" has been clicked)
elif response_id == Gtk.ResponseType.CANCEL:
print("cancelled: FileChooserAction.OPEN")
# destroy the FileChooserDialog
dialog.destroy()
# callback function for save_as
def save_as_callback(self, action, parameter):
# create a filechooserdialog to save:
# the arguments are: title of the window, parent_window, action,
# (buttons, response)
save_dialog = Gtk.FileChooserDialog("Pick a file", self,
Gtk.FileChooserAction.SAVE,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_SAVE, Gtk.ResponseType.ACCEPT))
# the dialog will present a confirmation dialog if the user types a file name that
# already exists
save_dialog.set_do_overwrite_confirmation(True)
# dialog always on top of the textview window
save_dialog.set_modal(True)
# if self.file has already been saved
if self.file is not None:
try:
# set self.file as the current filename for the file chooser
save_dialog.set_file(self.file)
except GObject.GError as e:
print("Error: " + e.message)
# connect the dialog to the callback function save_response_cb()
save_dialog.connect("response", self.save_response_cb)
# show the dialog
save_dialog.show()
# callback function for the dialog save_dialog
def save_response_cb(self, dialog, response_id):
save_dialog = dialog
# if response is "ACCEPT" (the button "Save" has been clicked)
if response_id == Gtk.ResponseType.ACCEPT:
# self.file is the currently selected file
self.file = save_dialog.get_file()
# save to file (see below)
self.save_to_file()
# if response is "CANCEL" (the button "Cancel" has been clicked)
elif response_id == Gtk.ResponseType.CANCEL:
print("cancelled: FileChooserAction.SAVE")
# destroy the FileChooserDialog
dialog.destroy()
# callback function for save
def save_callback(self, action, parameter):
# if self.file is not already there
if self.file is not None:
self.save_to_file()
# self.file is a new file
else:
# use save_as
self.save_as_callback(action, parameter)
# save_to_file
def save_to_file(self):
# get the content of the buffer, without hidden characters
[start, end] = self.buffer.get_bounds()
current_contents = self.buffer.get_text(start, end, False)
# if there is some content
if current_contents != "":
# set the content as content of self.file.
# arguments: contents, etags, make_backup, flags, 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)
# if the contents are empty
else:
# create (if the file does not exist) or overwrite the file in readwrite mode.
# arguments: etags, make_backup, flags, 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)
# app action quit, connected to the callback function
quit_action = Gio.SimpleAction.new("quit", None)
quit_action.connect("activate", self.quit_callback)
self.add_action(quit_action)
# get the menu from the ui file with a builder
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)
# callback function for 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>FileChooserDialog에 쓸만한 메서드</title>
<p>참고로 FileChooserDialog 동작은 <code>Gtk.FileChooserAction.OPEN</code>(사용자가 기존 파일을 선택하기만 할 수 있음) <code>Gtk.FileChooserAction.SAVE</code>(사용자가 기존 파일을 선택하거나, 새 파일 이름을 입력할 수 있음), <code>Gtk.FileChooserAction.SELECT_FOLDER</code>(사용자가 기존 폴더를 선택하기만 할 수 있음), <code>Gtk.FileChooserAction.CREATE_FOLDER</code>(사용자가 기존 폴더를 선택하거나, 새 폴더 이름을 입력할 수 있음) 중 하나일 수 있습니다.</p>
<p><link xref="#code"/>에서 사용한 메서드 주변을 보자면:</p>
<list>
<item><p><code>set_show_hidden(True)</code> 함수로 숨김 파일과 숨김 폴더를 나타냈습니다.</p></item>
<item><p><code>set_select_multiple(True)</code> 함수로 여러 파일을 선택할 수 있게 했습니다. <code>Gtk.FileChooserAction.OPEN</code> 또는 <code>Gtk.FileChooserAction.SELECT_FOLDER</code> 모드일 때만 가능합니다.</p></item>
<item><p>"다른 이름으로 저장" 대화 상자에서 <code>set_current_name(current_name)</code> 함수로 파일 선택 창의 <code>current_name</code>을 마치 사용자가 입력한 것처럼 설정했습니다. <code>current_name</code> 값은 <em>Untitled.txt</em>와 같은 값이 될 수 있습니다. 이 메서드는 "다른 이름으로 저장" 대화상자를 제외하고느 사용하지 않는게 좋습니다.</p></item>
<item><p>기본 현재 폴더는 "최근 항목" 입니다. 다른 폴더를 지정하려면 <code>set_current_folder_uri(uri)</code> 함수를 사용하십시오. 그러나 참고로 "다른 이름으로 저장" 명령을 사용하거나 이미 파일을 어딘가에 저장했을 경우에만 이 메서드를 사용하여 파일 선택 대화상자를 통해 지정 폴더를 나타내야합니다.</p></item>
</list>
</section>
<section id="references">
<title>API 참고서</title>
<p>이 예제는 다음 참고자료가 필요합니다:</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>