我想做什么
我正试图为木星笔记本制作一个互动的情节。这些函数都是在不同的文件中编写的,但它们的目的是在交互式笔记本会话中使用。我在matplotlib图上有一个Button小部件,单击它时,我希望打开一个文件对话框,用户可以在其中输入一个文件名来保存该图形。我在Mac (Mojav10.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。
发布于 2020-04-02 10:48:31
我找到了一种糟糕的、不干净的解决方案,但它似乎很有效。由于某些原因,直接打开QFileDialog不允许我激活它。它在活动窗口的后面打开,从它被调用的地方(朱庇特笔记本中的终端窗口或浏览器)而不响应键盘。因此,以下块中的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如果有人找到更优雅的解决方案,请告诉我。
编辑:当从命令行调用它时,这是有效的,但是仍然是,而不是从木星笔记本调用的。也尝试过this,但没有成功。文件对话框保留在浏览器窗口后面,不响应键盘。
https://stackoverflow.com/questions/60978916
复制相似问题