#!/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()
Page List
▼
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.