IPython Notebook: Open/select file with GUI (Qt Dialog)

When you perform the same analysis in a notebook on different data files, may be handy to graphically select a data file.

In my python scripts I usually implement a QT dialog that returns the file-name of the selected file:

from PySide import QtCore, QtGui

def gui_fname(dir=None):
    """Select a file via a dialog and return the file name.
    """
    if dir is None: dir ='./'
    fname = QtGui.QFileDialog.getOpenFileName(None, "Select data file...", 
            dir, filter="All files (*);; SM Files (*.sm)")
    return fname[0]

However, running this function from an notebook

full_fname = gui_fname()

causes the kernel to die (and restart):

Interestingly, puttying this 3 command in 3 separate cells works

%matplotlib qt
full_fname = gui_fname()
%matplotlib inline

but when I put those commands in one single cell the kernel dies again.

This prevents to create a function like gui_fname_ipynb() that transparently allows selecting a file with a GUI.

For convenience, I created a notebook illustrating the problem:

  • Open/select file with GUI (Qt Dialog)
  • Any suggestion on how to execute a dialog for file selection from within an IPython Notebook?


    This behaviour was a bug in IPython:

    https://github.com/ipython/ipython/issues/4997

    that was fixed here:

    https://github.com/ipython/ipython/pull/5077

    The function to open a gui dialog should work on current master and on the oncoming 2.0 release.

    To date, the last 1.x version (1.2.1) does not include a backport of the fix.

    EDIT: The example code still crashes IPython 2.x, see this issue.


    Using Anaconda 5.0.0 on windows (Python 3.6.2, IPython 6.1.0), the following two options are both working for me.

    OPTION 1: Entirely in a Jupyter notebook:

    CELL 1:

    %gui qt
    
    from PyQt5.QtWidgets import QFileDialog
    
    def gui_fname(dir=None):
        """Select a file via a dialog and return the file name."""
        if dir is None: dir ='./'
        fname = QFileDialog.getOpenFileName(None, "Select data file...", 
                    dir, filter="All files (*);; SM Files (*.sm)")
        return fname[0]
    

    CELL 2:

    gui_fname()
    

    This is working for me but it seems a bit...fragile. If I combine these two things into the same cell, it crashes. Or if I omit the %gui qt , it crashes. If I "restart kernel and run all cells", it doesn't work. So I kinda like this other option...

    MORE RELIABLE OPTION: Separate script that opens dialog box in a new process

    (Based on mkrog code here.)

    PUT THE FOLLOWING IN A SEPARATE PYTHON SCRIPT CALLED blah.py :

    from sys import executable, argv
    from subprocess import check_output
    from PyQt5.QtWidgets import QFileDialog, QApplication
    
    def gui_fname(directory='./'):
        """Open a file dialog, starting in the given directory, and return
        the chosen filename"""
        # run this exact file in a separate process, and grab the result
        file = check_output([executable, __file__, directory])
        return file.strip()
    
    if __name__ == "__main__":
        directory = argv[1]
        app = QApplication([directory])
        fname = QFileDialog.getOpenFileName(None, "Select a file...", 
                directory, filter="All files (*)")
        print(fname[0])
    

    ...AND IN YOUR JUPYTER NOTEBOOK

    import blah
    blah.gui_fname()
    
    链接地址: http://www.djcxy.com/p/18090.html

    上一篇: 如何在R中的主热图一侧添加额外的单列热图

    下一篇: IPython Notebook:使用GUI打开/选择文件(Qt对话框)