首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从jupyter笔记本打开PyQt5保存文件对话框以保存matplotlib图

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

Stack Overflow用户
提问于 2020-04-01 19:31:58
回答 1查看 571关注 0票数 0

我想做什么

我正试图为木星笔记本制作一个互动的情节。这些函数都是在不同的文件中编写的,但它们的目的是在交互式笔记本会话中使用。我在matplotlib图上有一个Button小部件,单击它时,我希望打开一个文件对话框,用户可以在其中输入一个文件名来保存该图形。我在Mac (Mojav10.14.6)上,Tkinter给了我很大的问题(完全系统崩溃),所以我尝试用PyQt5来实现这一点。

代码

代码语言:javascript
复制
-----------
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。

EN

回答 1

Stack Overflow用户

发布于 2020-04-02 10:48:31

我找到了一种糟糕的、不干净的解决方案,但它似乎很有效。由于某些原因,直接打开QFileDialog不允许我激活它。它在活动窗口的后面打开,从它被调用的地方(朱庇特笔记本中的终端窗口或浏览器)而不响应键盘。因此,以下块中的save函数不能像预期的那样在Mac上工作:

代码语言:javascript
复制
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

如果文件对话框是从一个小部件中打开的,那么就可以工作了。因此,使用从未出现在屏幕上的虚拟小部件确实对我有效,至少在命令行中是这样的:

代码语言:javascript
复制
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

如果有人找到更优雅的解决方案,请告诉我。

编辑:当从命令行调用它时,这是有效的,但是仍然是,而不是从木星笔记本调用的。也尝试过this,但没有成功。文件对话框保留在浏览器窗口后面,不响应键盘。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60978916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档