#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
PyQt4 conversion of Qt Application Example
Implement the remaining actions:
_newFile(), _open(), _about(), _loadFile(),
_documentWasModified(), _strippedName()
Re-write _setCurrentFile()
BEHAVIOUR:
=========
When the open document is modified an asterisk appears
by the file name in the Window title.
When a new document is loaded, the Window title is updated
to reflect the file name.
All the Edit functions work.
NOTES:
=====
_setCurrentFile() was re-written to use _setWindowTitle()
rather than _setWindowFilePath().
Used Python os.path rather than QFileInfo to get the file
name from the full path.
last modified: 2012-01-27 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)
self._newFile() # force the window title
# overridden methods ------------------------------------------------------
def closeEvent(self, evt):
if self._maybeSave():
self._writeSettings()
evt.accept()
else:
evt.ignore()
# private slots -----------------------------------------------------------
@pyqtSlot()
def _newFile(self):
if self._maybeSave():
self._textEdit.clear()
self._setCurrentFile('untitled.txt')
@pyqtSlot()
def _open(self):
if self._maybeSave():
fname = QFileDialog.getOpenFileName(self)
if fname:
self._loadFile(fname)
@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):
QMessageBox.about(self,
self.tr("About Application"),
self.tr("The Application example demonstrates\n"
"how to write modern GUI applications using Qt\n"
"with a menubar, toolbars, and a status bar."))
@pyqtSlot()
def _documentWasModified(self):
self.setWindowModified(self._textEdit.document().isModified())
# 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):
with open(fname, 'r') as f:
txt = f.read()
self._textEdit.setPlainText(txt)
self._setCurrentFile(fname)
self.statusBar().showMessage(self.tr("File loaded."))
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)
self.setWindowTitle(self.tr("{0} [*] - Application Example".format(
self._strippedName(self._curFile))))
def _strippedName(self, fullFname):
return os.path.basename(fullFname)
# 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()
Thursday, January 26, 2012
Qt 4.8 Application Example - Part 5
Finally figured out what was going on with the Window title; the string used in setting the title has to include a parameter [*], also need to use setWindowTitle(), not _setWindowFilePath(). Re-wrote _setCurrentFileName() and_strippedName(); implemented the remaining methods/slots and we're done.
Labels:
Qt Application Example