IPython笔记本:使用GUI打开/选择文件(Qt对话框)

IPython笔记本:使用GUI打开/选择文件(Qt对话框),ipython,ipython-notebook,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 = QtGu

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

在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]
但是,从笔记本上运行此功能

full_fname = gui_fname()
导致内核死亡(并重新启动):

有趣的是,将这3个命令放在3个单独的单元格中可以工作

%matplotlib qt
full_fname = gui_fname()
%matplotlib inline
但是当我把这些命令放在一个单元格中时,内核又死掉了

这会阻止创建类似于
gui\u fname\u ipynb()
的函数,该函数透明地允许使用gui选择文件

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


关于如何在IPython笔记本中执行文件选择对话框的任何建议?

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

这是固定的:

打开gui对话框的功能应该可以在当前主版本和即将发布的2.0版本上使用

到目前为止,最新的1.x版本(1.2.1)没有包含补丁的后端口


编辑:示例代码仍然会使IPython 2.x崩溃,请参见。

在windows上使用Anaconda 5.0.0(Python 3.6.2,IPython 6.1.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]
单元2:

gui_fname()
这对我来说很有效,但似乎有点…脆弱。如果我把这两个东西合并到同一个单元格中,它就会崩溃。或者如果我省略了
%guiqt
,它就会崩溃。如果我“重新启动内核并运行所有单元”,它将无法工作。所以我有点喜欢另一个选择

更可靠的选项:在新进程中打开对话框的单独脚本 (基于mkrog代码。)

将以下内容放在名为
blah.py
的单独PYTHON脚本中:

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])
…在你的JUPYTER笔记本上

import blah
blah.gui_fname()

我有一个通用代码,它可以毫无问题地完成它的工作。这是我的建议:

try:
    from tkinter import Tk
    from tkFileDialog import askopenfilenames
except:
    from tkinter import Tk
    from tkinter import filedialog

Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
filenames = filedialog.askopenfilenames() # show an "Open" dialog box and return the path to the selected file

print (filenames)

希望有用

如果jupyter lab实例与浏览器运行在同一主机上,所有这些解决方案是否正确?这不适用于jupyter Classic Notebook v6.1.5或Spyder v4.2.3。它挂起iPythonNB内核,并需要重新启动服务器内核。我试着在Spyder中使用它,它会打开Tkinter对话框,但只是作为一个“弹出窗口”,然后在选择一个文件后,文件名永远不会返回到调用程序。这让我在2021年投了反对票。这对我在Windows 10上使用Jupyter(经典)笔记本v6.1.5很有效,但它有点笨重,因为我希望笔记本是独立的。因此,我使用iPython笔记本神奇命令“%%writefile>”将上面的Python输入单元格源代码写入本地文件,然后导入模块并在下一个单元格中运行它。Qt文件选择器打开时是一个“弹出窗口”,而不是一个弹出对话框,这有点麻烦。然而,它是有效的。非常感谢。