2017-01-16 165 views
2

我正在用Python 3.5編寫應用程序& PyQT 5.在這個應用程序中,我有一個嵌入式matplotlib畫布和一個嵌入式matplotlib NavigationToolbar。應用程序測量一些數據,然後繪製它們。用戶在某個時候想要導出圖並將其保存到某個地方的「.png」文件中,然後測量新的東西。如何在PyQt5應用程序中從Matplotlib NavigationToolbar更改默認文件名?

爲此,我一直在使用NavigationToolbar上的「軟盤」/「保存」圖標,它運行良好。但是,單擊它時,會在程序的根文件夾(或上次打開的文件夾)中打開一個對話框,並將保存的圖像的名稱預先填充爲「image.png」。

我想將此預先填入的默認名稱更改爲我的程序自定義的內容,例如「measurement_7453243.png」或「2017_01_16_measurement.png」。有沒有一種方法可以讓我做到這一點?

想法#1:我發現是使用matplotlib.rcParams ['savefig.directory']並使用它來設置對話框應該打開的目錄的選項 - 不是文件名。我似乎無法找到會更改默認文件名的'savefig.XXXX'屬性。想法#2:我可以在NavigationToolbar之外的應用程序中創建一個自定義按鈕,它將使用Qt運行自定義文件保存對話框,然後使用savefig()保存該數字。但是,爲什麼這樣做,如果已經有一個很好的按鈕,幾乎是我想要的?

任何提示和想法,以及「這不能做」與適當的來源將不勝感激。

+1

我曾經有過同樣的問題,在找不到快速解決方案之後,我實現了您所謂的Idea#2。儘管如此,我確信有一個解決方案。 – ImportanceOfBeingErnest

回答

3

默認文件名由方法FigureCanvasBase.get_default_filename提供。你可以只猴子修補它在畫布上被創建後:

canvas = FigureCanvas(fig) 
canvas.get_default_filename = lambda: 'new_default_name.png' 

我想雖然正確的方法是繼承FigureCanvas,覆蓋的方法,也許提供了一個API來設置默認文件名。

下面是使用猴子打補丁Qt5Agg爲例,改編自matplotlib文檔:

from PyQt5.QtWidgets import (
    QMainWindow, QApplication, QWidget, QVBoxLayout) 

from matplotlib.figure import Figure 
from matplotlib.backends.backend_qt5agg import (
    FigureCanvasQTAgg as FigureCanvas, 
    NavigationToolbar2QT as NavigationToolbar) 


class AppForm(QMainWindow): 
    def __init__(self, parent=None): 
     QMainWindow.__init__(self, parent) 
     main_frame = QWidget() 

     fig = Figure((5.0, 4.0), dpi=100) 
     ax = fig.add_subplot(111) 
     ax.plot([1, 2, 4, 8]) 

     canvas = FigureCanvas(fig) 
     canvas.get_default_filename = lambda: 'new_default_name.png' 
     mpl_toolbar = NavigationToolbar(canvas, main_frame) 

     vbox = QVBoxLayout() 
     vbox.addWidget(canvas) # the matplotlib canvas 
     vbox.addWidget(mpl_toolbar) 
     main_frame.setLayout(vbox) 
     self.setCentralWidget(main_frame) 


app = QApplication(['Test']) 
form = AppForm() 
form.show() 
app.exec_() 
+0

謝謝你的回答,我會試試看看它是如何與我的程序:)。 – erthy

+0

我在我的應用程序中嘗試了這一點,我無法啓動它。調用成功(即不會拋出異常),但在保存圖形時也不會改變任何內容。 你有沒有機會提供一個工作示例? – erthy

+0

@erthy我很困惑。昨天在一個平行宇宙'fig.set_label'上做了你想要的獨立互動數字。現在它是'fig.canvas.set_window_title',但不幸的是它在嵌入式數字中沒有做任何事情,所以我不得不尋找另一種方式。我準備了一個[mcve],以防萬一我再次轉移到另一個宇宙。 – Goyo

1

不知道,如果你總是可以做到這一點,但對我來說這個數字實例有一個帆布屬性,我可以monkeypatch建議爲Goyo

import matplotlib.pyplot as plt 
f = plt.figure() 
c = f.canvas 
my_adventurous_filename = 'figure-III' # irony 
c.get_default_filename = lambda : '%s.%s' % (my_adventurous_filename, 
              c.get_default_filetype()) 
plt.show() 
相關問題