从jupyter笔记本打开PyQt5保存文件对话框以保存matplotlib图

问题描述 投票:0回答:1

我想做什么

我正在尝试为Jupyter笔记本做一个交互式绘图。这些功能全部写在不同的文件中,但它们的预期用途是在交互式笔记本会话中使用。我在matplotlib图形上有一个Button小部件,单击该按钮时,我想打开一个文件对话框,用户可以在其中输入文件名来保存图形。我使用的是Mac OSX(Mojave 10.14.6),Tkinter给我带来了主要问题(完整的系统崩溃),因此我尝试使用PyQt5来实现。

代码

-----------
plotting.py
-----------
from . import file_dialog as fdo
import matplotlib.pyplot as plt
import matplotlib.widgets as wdgts

def plot_stack(stack):
    fig, ax = plt.subplots(figsize=(8, 6))
    plt.subplots_adjust(bottom=0.25, left=-0.1)

    ...  # plotting happens here

    # button for saving
    def dosaveframe(event):
        fname = fdo.save()
        fig.savefig(fname) # to be changed to something more appropriate

    savea = plt.axes([0.65, 0.8, 0.15, 0.05], facecolor=axcolor)
    saveb = Button(savea, "save frame", hovercolor="yellow")
    saveb.on_clicked(dosaveframe)
    savea._button = saveb  # for persistence

    plt.show()

--------------
file_dialog.py
--------------
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import (QWidget, QFileDialog)

class SaveFileDialog(QWidget):

    def __init__(self, text="Save file", types="All Files (*)"):
        super().__init__()
        self.title = text
        self.setWindowTitle(self.title)
        self.types = types
        self.filename = self.saveFileDialog()
        self.show()

    def saveFileDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        filename, _ = (
            QFileDialog.getSaveFileName(self, "Enter filename",
                                        self.types, options=options))
        return filename

def save(directory='./', filters="All files (*)"):
    """Open a save file dialog"""
    app = QApplication([directory])
    ex = SaveFileDialog(types=filters)
    return ex.filename
    sys.exit(app.exec_())

什么不起作用

保存对话框打开,它响应鼠标,但不响应键盘。不管我是否选择小窗口,键盘都保持与笔记本电脑的连接,因此当我按“ s”时,它将保存笔记本电脑。因此,用户无法输入文件路径。我该如何工作?我有Anaconda,PyQt 5.9.2,matplotlib 3.1.1,jupyter 1.0.0。

matplotlib jupyter-notebook pyqt5 macos-mojave qfiledialog
1个回答
0
投票

我发现了一种非常糟糕,不干净的解决方案,但它似乎可以工作。由于某些原因,直接打开QFileDialog不允许我激活它。它在被调用的活动窗口(Jupyter Notebook中的终端窗口或浏览器)后面打开,并且不响应键盘。因此,以下块中的save功能在Mac上无法正常运行:

from PyQt5.QtWidgets import QApplication, QFileDialog

def save(directory='./', filters="All files (*)"):
    app = QApplication([directory])
    path, _ = QFileDialog.getSaveFileName(caption="Save to file",
                                          filter=filters,
                                          options=options)
    return path

起作用的是从小部件打开文件对话框。因此,至少在命令行中,使用永远不会显示在屏幕上的虚拟小部件确实对我有用:

from PyQt5.QtWidgets import (QApplication, QFileDialog, QWidget)


class DummySaveFileDialogWidget(QWidget):

    def __init__(self, title="Save file", filters="All Files (*)"):
        super().__init__()
        self.title = title
        self.filters = filters
        self.fname = self.savefiledialog()

    def savefiledialog(self):
        filename, _ = QFileDialog.getSaveFileName(caption=self.title,
                                                  filter=self.filters,
                                                  options=options)
        return filename

def save(directory='./', filters="All files (*)"):
    app = QApplication([directory])
    form = DummySaveFileDialogWidget()
    return form.fname

如果有人找到了更有效的解决方案,请告诉我


编辑:当从命令行调用它时有效,但是仍然不是从Jupyter笔记本中。也尝试过this,没有成功。文件对话框位于浏览器窗口的后面,并且不响应键盘。

© www.soinside.com 2019 - 2024. All rights reserved.