【发布时间】:2020-04-01 19:31:58
【问题描述】:
我想做的事
我正在尝试为 Jupyter Notebook 制作交互式绘图。这些函数都写在不同的文件中,但它们的预期用途是在交互式笔记本会话中。我在 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。
【问题讨论】:
-
另一位用户刚刚发布了this question 一个非常相似的问题(问题不同,但提供的代码是错误的)。我不使用 Jupyter,所以我不能保证它会解决你的问题,但尽管如此,你绝对应该不创建一个 QWidget 来显示一个 QFileDialog,也不应该等待一个阻塞函数就像
__init__中的getSaveFileName一样(这可能是您问题的根源):只需调用该函数即可获取路径。另外,末尾的sys.exit完全没用,因为它在return之后。 -
感谢您抽出宝贵时间回复我的问题。我应该提到我的小部件解决方案已经是一种解决方法:我之前尝试过的链接中描述的直接简单方法。在这种情况下,我认为文件对话框根本没有打开。然后我发现文件对话框是在浏览器窗口后面打开的。在这两种方法中,我都无法在文件对话框中输入。至少我已经发现这不是 jupyter notebook 独有的行为:如果我从命令行调用
save,它还会打开一个我无法输入的文件对话框。会不会是 Mac 上的 Qt 错误? -
Jupyter 是一个网络应用程序。 tkinter 和 Qt 是独立的应用程序,它们并不能很好地与 Jupyter 一起工作。我认为你可以使用 ipywidgets 在 Jupyter 中做你想做的事情。没有理由从 Jupyter 启动子进程以在 QT 或 tkinter 中运行单独的独立图形界面。
标签: matplotlib jupyter-notebook pyqt5 macos-mojave qfiledialog