IPython Notebook:使用GUI打开/选择文件(Qt Dialog)

use*_*916 10 ipython ipython-notebook

当您在笔记本上对不同的数据文件执行相同的分析时,可以方便地以图形方式选择数据文件.

在我的python脚本中,我通常会实现一个QT对话框,它返回所选文件的文件名:

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]
Run Code Online (Sandbox Code Playgroud)

但是,从笔记本运行此功能

full_fname = gui_fname()
Run Code Online (Sandbox Code Playgroud)

导致内核死亡(并重启):

有趣的是,将3个命令放在3个单独的单元格中

%matplotlib qt
full_fname = gui_fname()
%matplotlib inline
Run Code Online (Sandbox Code Playgroud)

但是当我将这些命令放在一个单元中时,内核会再次死掉.

这可以防止创建类似于gui_fname_ipynb()透明地允许使用GUI选择文件的功能.

为方便起见,我创建了一个说明问题的笔记本:

有关如何在IPython Notebook中执行文件选择对话框的任何建议吗?

Ste*_*nes 6

在Windows(Python 3.6.2,IPython 6.1.0)上使用Anaconda 5.0.0时,以下两个选项对我都有效。

选项1:完全在Jupyter笔记本中:

单元格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]
Run Code Online (Sandbox Code Playgroud)

单元格2:

gui_fname()
Run Code Online (Sandbox Code Playgroud)

这对我有用,但似乎有点脆弱。如果将这两件事组合到同一个单元格中,则会崩溃。或者,如果我省略%gui qt,它会崩溃。如果我“重新启动内核并运行所有单元”,则无法正常工作。所以我有点喜欢这个其他选择...

更可靠的选择:在新进程中打开对话框的单独脚本

(基于此处的 mkrog代码。)

将以下内容放入单独的PYTHON脚本中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])
Run Code Online (Sandbox Code Playgroud)

...并在您的JUPYTER笔记本中

import blah
blah.gui_fname()
Run Code Online (Sandbox Code Playgroud)


use*_*916 2

此行为是 IPython 中的一个错误:

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

已修复:

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

打开 GUI 对话框的功能应该适用于当前的主版本和即将发布的 2.0 版本。

迄今为止,最新的 1.x 版本 (1.2.1)包含修复程序的向后移植。

编辑:示例代码仍然会使 IPython 2.x 崩溃,请参阅此问题