PyGTK: gtk.FileChooserButton shows folder not identical to gtk.FileChooserButton.get_current_folder()

StackOverflow https://stackoverflow.com/questions/14086798

  •  13-12-2021
  •  | 
  •  

質問

I have a problem with gtk.FileChooserButton in a Python script. If you choose the option ›Other ...‹ from the button menu, the gtk.FileChooserDialog opens where you can select a new folder. If I select this new folder by double-clicking it and confirm the dialog by clicking on ›Open‹, the selected folder name is displayed in gtk.FileChooserButton and the value of gtk.FileChooserButton.get_current_folder() changes to the path of the selected folder (as you can see in the status bar of the example). This is the expected behaviour.

But when I select the new folder not by double-clicking but only by a single click, and confirm the dialog by clicking on ›Open‹, the selected folder name is displayed in gtk.FileChooserButton, but the path in gtk.FileChooserButton.get_current_folder() is not the path of the selected folder but of its parent folder.

Is that a bug or is there an error in my script? The folder name on the button should always be identical to that of gtk.FileChooserButton.get_current_folder(). What can be done here? Thanks.

#!/usr/bin/python
# -*- coding: utf-8 -*-

import gtk, os

class MainClass(object):
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_position(gtk.WIN_POS_CENTER)
        self.window.set_default_size(400, 100)
        self.window.connect("delete_event", self.delete_event)
        self.window.connect("destroy", self.destroy)
        self.window.set_border_width(6)
        self.vbox1 = gtk.VBox(False, 0)
        self.window.add(self.vbox1)

        self.filechooserdialog1 = gtk.FileChooserDialog("Select a folder…", None, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        self.filechooserdialog1.set_default_response(gtk.RESPONSE_OK)
        self.filechooserbutton1 = gtk.FileChooserButton(self.filechooserdialog1)
        self.filechooserbutton1.set_current_folder(os.environ['HOME'])
        self.filechooserbutton1.connect('current-folder-changed', self.tell_folder)

        self.vbox1.pack_start(self.filechooserbutton1, True, False, 0)
        self.statusbar1 = gtk.Statusbar()
        self.vbox1.pack_start(self.statusbar1, False, False, 0)
        self.context_id = self.statusbar1.get_context_id("status")
        self.window.show_all()

    def tell_folder(self, data=None):
        self.statusbar1.push(self.context_id, self.filechooserbutton1.get_current_folder())

    def delete_event(self, widget, event, data=None):
        return False

    def destroy(self, data=None):
        gtk.main_quit()

    def main(self):
        gtk.main()

if __name__ == "__main__":
    MyApp = MainClass()
    MyApp.main()
役に立ちましたか?

解決

The signal you're listening to, only gets emitted when the view-folder in the file chooser changes, not when selecting a folder inside a parent folder, the same goes for get_current_folder(), it will tell you which folder you're looking at rather than which you selected. So what happened in your code is that the double-click first changed the current folder and then "pressed" OK.

It would seem more fit to listen to the file-set signal of the FileChooserButton, though I'm not 100% sure how you check if the user clicked on any button/exited the dialogue. To get what is selected, provided that you only allow for selecting one thing at a time, you could use the FileChooser's get_filename() (or get_filenames() if you allow multi-select). Unfortunately I can't test the solution, because I'm on the wrong computer, but it should lead you in the right direction at least.

As a side-note, I find it easier to simply invoke run() of the FileChooserDialog when I need the dialogue and catch what it returns as the response (what button was clicked) and then use get_filename().

他のヒント

If you want the current folder it is good to monitor the current-folder-changed signal then you can use get_current_folder in the callback but reliably only in the callback. Here is a decent workaround.

def on_current_folder_changed(widget):
    widget._folder = widget.get_current_folder()

def on_file_set(widget):
    # Lock that value in.
    if widget.get_current_folder() != widget._folder:
        widget.set_current_folder(widget._folder)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top