There were a few problems; for one, Where were the settings being written? Turns out the default under Windows is the Windows Registry; I re-wrote the code to create the settings as an .ini file.
Another problem was the handing of the Window title and what happens to it when the document is modified? It is not working correctly, but I did eventually figure it out ... in Part 5.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
PyQt4 conversion of Qt Application Example
Implement the last two methods called by '__init__()':
_readSettings()
_setCurrentFileName()
Implement closeEvent(), _maybeSave(), _save(), _saveAs(),
_saveFile(), _writeSettings()
BEHAVIOUR:
=========
On starting the application, saved settings are restored.
When the application is closed, if there are any pending
changes to the document, the user is prompted to save them.
The application position and size are saved and the
application exits.
NOTES:
=====
Re-wrote the way 'settings' were being handled. The
default in Windows is to update the Windows register. Prefer
to use an .ini file. Key change is code added to __init__()
where a 'settings' attribute is created using the QSettings
default method after setting the QSettings format to IniFormat.
The default call takes the application name and organization
from values defined in main(). Note that the application version
is ignored. On Windows, the .ini file is named "Application Example.ini"
in path:
user/appdata/local/my business [may show up in 'roaming'
The implemented methods are connected:
closeEvent() calls maybeSave()
which calls save() which may call saveAs()
both save() and saveAs() call saveFile()
There is a problem with the window title, it is not
being set.
There is also a problem on exiting, asked to save
even though the document hasn't been modified.
last modified: 2012-01-25 jg
ref:
http://developer.qt.nokia.com/doc/qt-4.8/mainwindows-application.html
'''
import sys, os
from PyQt4.QtGui import (QApplication, QMainWindow, QPlainTextEdit, QAction,
QIcon, QKeySequence, QFileDialog, QMessageBox)
from PyQt4.QtCore import (pyqtSlot, QSettings, QPoint, QSize)
import qrc_app
class MainWindow(QMainWindow): # subclass QMainWindow
def __init__(self, parent=None): # initialise base class
super(MainWindow, self).__init__(parent)
# create central widget
self._textEdit = QPlainTextEdit()
self.setCentralWidget(self._textEdit)
# create GUI
self._createActions()
self._createMenus()
self._createToolBars()
self._createStatusBar()
# connect signals/slots for event handling
self._textEdit.document().contentsChanged.connect(self._documentWasModified)
# create application settings object
QSettings.setDefaultFormat(QSettings.IniFormat)
self._settings = QSettings()
# establish initial conditions
self._readSettings()
self._setCurrentFile('')
self.setUnifiedTitleAndToolBarOnMac(True)
# overridden methods ------------------------------------------------------
def closeEvent(self, evt):
if self._maybeSave():
self._writeSettings()
evt.accept()
else:
evt.ignore()
# private slots -----------------------------------------------------------
@pyqtSlot()
def _newFile(self):
pass
@pyqtSlot()
def _open(self):
pass
@pyqtSlot()
def _save(self):
if not self._curFile:
return self._saveAs()
else:
return self._saveFile(self._curFile)
@pyqtSlot()
def _saveAs(self):
fname = QFileDialog.getSaveFileName(self)
if not fname:
return False
return self._saveFile(fname)
@pyqtSlot()
def _about(self):
pass
@pyqtSlot()
def _documentWasModified(self):
pass
# private methods ---------------------------------------------------------
def _createActions(self):
self._newAct = QAction(QIcon(":/images/new.png"), self.tr("&New"), self)
self._newAct.setShortcuts(QKeySequence.New)
self._newAct.setStatusTip((self.tr("Create a new file.")))
self._newAct.triggered.connect(self._newFile)
self._openAct = QAction(QIcon(":/images/open.png"), self.tr("&Open"), self)
self._openAct.setShortcuts(QKeySequence.Open)
self._openAct.setStatusTip((self.tr("Open a file.")))
self._openAct.triggered.connect(self._open)
self._saveAct = QAction(QIcon(":/images/save.png"), self.tr("&Save"), self)
self._saveAct.setShortcuts(QKeySequence.Save)
self._saveAct.setStatusTip((self.tr("Save the document to disk.")))
self._saveAct.triggered.connect(self._save)
self._saveAsAct = QAction(self.tr("Save &As..."), self)
self._saveAsAct.setShortcuts(QKeySequence.SaveAs)
self._saveAsAct.setStatusTip((self.tr("Save the document under a new name.")))
self._saveAsAct.triggered.connect(self._saveAs)
self._exitAct = QAction(self.tr("E&xit"), self)
self._exitAct.setShortcuts(QKeySequence.Quit)
self._exitAct.setStatusTip((self.tr("Exit the application.")))
self._exitAct.triggered.connect(self.close)
self._aboutAct = QAction(self.tr("&About"), self)
self._aboutAct.setStatusTip((self.tr("Show the application's About box.")))
self._aboutAct.triggered.connect(self._about)
self._aboutQtAct = QAction(self.tr("About &Qt"), self)
self._aboutQtAct.setStatusTip((self.tr("Show the Qt library's About box.")))
self._aboutQtAct.triggered.connect(QApplication.instance().aboutQt)
# actions that connect to the 'textEdit' widget
self._cutAct = QAction(QIcon(":/images/cut.png"), self.tr("Cu&t"), self)
self._cutAct.setShortcuts(QKeySequence.Cut)
self._cutAct.setStatusTip((self.tr("Cut the current selection's content to the clipboard.")))
self._cutAct.triggered.connect(self._textEdit.cut)
self._copyAct = QAction(QIcon(":/images/copy.png"), self.tr("&Copy"), self)
self._copyAct.setShortcuts(QKeySequence.Copy)
self._copyAct.setStatusTip((self.tr("Copy the current selection's content to the clipboard.")))
self._copyAct.triggered.connect(self._textEdit.copy)
self._pasteAct = QAction(QIcon(":/images/paste.png"), self.tr("&Paste"), self)
self._pasteAct.setShortcuts(QKeySequence.Paste)
self._pasteAct.setStatusTip((self.tr("Paste the clipboard contents into the current selection.")))
self._pasteAct.triggered.connect(self._textEdit.paste)
# set action visibility
self._cutAct.setEnabled(False)
self._copyAct.setEnabled((False))
self._textEdit.copyAvailable.connect(self._cutAct.setEnabled)
self._textEdit.copyAvailable.connect(self._copyAct.setEnabled)
def _createMenus(self):
fileMenu = self.menuBar().addMenu(self.tr("&File"))
fileMenu.addAction(self._newAct)
fileMenu.addAction(self._openAct)
fileMenu.addAction(self._saveAct)
fileMenu.addAction(self._saveAsAct)
fileMenu.addSeparator()
fileMenu.addAction(self._exitAct)
editMenu = self.menuBar().addMenu(self.tr("&Edit"))
editMenu.addAction(self._cutAct)
editMenu.addAction(self._copyAct)
editMenu.addAction(self._pasteAct)
self.menuBar().addSeparator()
helpMenu = self.menuBar().addMenu(self.tr("&Help"))
helpMenu.addAction(self._aboutAct)
helpMenu.addAction(self._aboutQtAct)
def _createToolBars(self):
fileToolBar = self.addToolBar(self.tr("File"))
fileToolBar.addAction(self._newAct)
fileToolBar.addAction(self._openAct)
fileToolBar.addAction(self._saveAct)
editToolBar = self.addToolBar(self.tr("Edit"))
editToolBar.addAction(self._cutAct)
editToolBar.addAction(self._copyAct)
editToolBar.addAction(self._pasteAct)
def _createStatusBar(self):
self.statusBar().showMessage(self.tr("Ready"))
def _readSettings(self):
pos = self._settings.value("pos", QPoint(200, 200))
size = self._settings.value("size", QSize(400, 400))
self.resize(size)
self.move(pos)
def _writeSettings(self):
self._settings.setValue("pos", self.pos())
self._settings.setValue("size", self.size())
def _maybeSave(self):
if self._textEdit.document().isModified:
ret = QMessageBox.warning(
self,
self.tr("Application"),
self.tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox.Save | QMessageBox.Discard |
QMessageBox.Cancel)
if ret == QMessageBox.Save:
return self._save()
elif ret == QMessageBox.Cancel:
return False
return True
def _loadFile(self, fname):
pass
def _saveFile(self, fname):
with open(fname, 'w') as f:
f.write(self._textEdit.toPlainText())
self._setCurrentFile(fname)
self.statusBar().showMessage(self.tr("File saved."))
return True
def _setCurrentFile(self, fname):
self._curFile = fname
self._textEdit.document().setModified(False)
self.setWindowModified(False)
shownName = self._curFile
if not self._curFile:
shownName = "untitled.txt"
self.setWindowFilePath(shownName)
def _strippedName(self, fullFname):
pass
# main ========================================================================
def main():
app = QApplication(sys.argv)
app.setOrganizationName("My Business")
app.setApplicationName("Application Example")
app.setApplicationVersion("1.0")
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()