9

When writing python scripts, QGIS does not save them when the user saves his main project with the ctrl+S command or with Project->Save. Besides, when leaving QGIS, the program does not warn about unsaved changes in python scripts even if it warns about unsaved changes to the project and offers to save them.

Is there any option to change this behaviour?

I should add that using the dialogue option to save the project when quitting does indeed save the project, but not the python scripts. Those are simply lost.

  • 2
    Good point, would be nice to have a warning, I made my painful experience too, when I accidentally closed and saved the project, where the python script changes were lost... I do not have a solution, but my workaround is to use an external text editor (I am using Atom link ). This saves your changes and Qgis will automatically reload your scipt, even when already open... – ADorsch Jan 10 '17 at 6:03
  • 3
    If you're running your script in the Python Console Editor, there is an option "Auto-save script before running" which does as it says. This won't answer your question but might help you save the changes you make when running the scripts. – Joseph Jan 10 '17 at 10:40
4

If you want to save the current python script in the Python Editor each time you save your project, type the following into the console:

from PyQt4.QtGui import QDockWidget
def save_project():
    consoleWidget = iface.mainWindow().findChild( QDockWidget, 'PythonConsole' )
    consoleWidget.console.saveScriptFile()

QgsProject.instance().projectSaved.connect(save_project)

This essentially connects the projectSaved() signal to the saveScriptFile() function in the python console.


Credit to Germán Carrillo for his answer in this post in which the above answer was based on.



Edit:

One method of automatically saving all scripts is to slightly modify your processing console.py file which can be found in your QGIS directory. For example:

C:/Program Files/QGIS 2.18/apps/qgis/python/console/console.py

Find the def saveScriptFile(self): function and replace the first line:

tabWidget = self.tabEditorWidget.currentWidget()

with the following and indent everything after:

for i in range(self.tabEditorWidget.count()):
    tabWidget = self.tabEditorWidget.widget(i)

So that it looks like:

def saveScriptFile(self):
    for i in range(self.tabEditorWidget.count()):
        tabWidget = self.tabEditorWidget.widget(i)
        try:
            tabWidget.save()
        except (IOError, OSError) as error:
            msgText = QCoreApplication.translate('PythonConsole',
                                                 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                              error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)

Save the file.

Now we need to create a startup.py file in your /.qgis2/python/ directory, this file is loaded when QGIS starts up so it will run any code saved inside. Include the following code:

from qgis.core import QgsProject
from qgis.utils import iface
from PyQt4.QtGui import QDockWidget
def save_project():
    consoleWidget = iface.mainWindow().findChild( QDockWidget, 'PythonConsole' )
    consoleWidget.console.saveScriptFile()

QgsProject.instance().projectSaved.connect(save_project)

Save the file.

Now, hopefully, when you load QGIS and save a project, all opened scripts in the console editor should be saved.


(Note: I'm quite certain you can iterate through the opened scripts in the console editor but haven't found it yet. This would be a much better and less intrusive method as it avoids altering the source code.)

  • 1
    Nice code which hints toward an answer. However, this only saves the current python script in the Python Editor (as you said), but other scripts are not saved... Besides, this behaviour is lost once closing QGIS. Still giving you an upvote for the nice answer =) – almerillat Jan 13 '17 at 20:04
  • @almerillat - Thanks, I've edited the post to include a possible method :) – Joseph Jan 16 '17 at 15:00
  • 1
    Wow, impressive. This works like a charm as long as you indent with spaces and not tabs (as I mistakenly did). As long as no better solution is available, I'll accept it. Thank you ! – almerillat Jan 18 '17 at 20:06
  • @almerillat Most welcome, glad it worked! Yes, hopefully a better solution will be posted :) – Joseph Jan 19 '17 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.