Monday, January 23, 2012

Qt 4.8 Notepad Tutorial - Part 5

The following code is based on the Qt Getting Started Programming with Qt Hello Notepad tutorial. There are five parts in all.


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

'''
    PyQt4 conversion of Qt Tutorial 'Hello Notepad'
    
    In this example, we will implement the functionality of the open() 
    and save() slots that we added in the previous example.    
    
    NOTES:
    =====
    The text editor is defined as a 'private attribute'. It is the only
    variable requiring access by other methods within the class.
    
    The built-in dialog QFileDialog is called by both the 'Open'
    and 'Save' methods; allowing the user to easily select and save
    files.

    Files are read and written using 'streams'. Refer to the online
    documentation for more information.
    
last modified: 2012-01-23 jg
ref: 
    http://developer.qt.nokia.com/doc/qt-4.8/gettingstartedqt.html
    http://riverbankcomputing.co.uk/static/Docs/PyQt4/html/qtextstream.html#details
'''
import sys
from PyQt4.QtGui import (QApplication, QMainWindow, QAction, QTextEdit,
                         QFileDialog, QMessageBox)
from PyQt4.QtCore import (pyqtSlot, QFile, QIODevice, QTextStream)

class Notepad(QMainWindow):

    def __init__(self, parent=None):
        super(Notepad, self).__init__(parent)

        # define menu actions
        openAction = QAction(self.tr("&Open..."), self)
        saveAction = QAction(self.tr("&Save..."), self)
        exitAction = QAction(self.tr("&Exit"), self)

        # set up signal/slot connections for event handling
        openAction.triggered.connect(self._open)
        saveAction.triggered.connect(self._save)
        exitAction.triggered.connect(QApplication.instance().quit)

        # create a dropdown 'File' menu on the window menu bar
        fileMenu = self.menuBar().addMenu(self.tr("&File..."))

        # add the open and save actions to the File menu
        fileMenu.addAction(openAction)
        fileMenu.addAction(saveAction)

        # add the exit action to the menu bar as a separate menu item
        self.menuBar().addAction(exitAction)

        # create the textEdit widget and add it as
        # the central widget for the window
        self._textEdit = QTextEdit()
        self.setCentralWidget(self._textEdit)

        self.setWindowTitle(self.tr("Notepad"))

    # define private slots (methods) ------------------------------------------
    @pyqtSlot()
    def _open(self):
        fileName = QFileDialog.getOpenFileName(self,
                                               self.tr("Open file..."),
                                               "",
                                               self.tr("Text files (*.txt);;Python files (*.py *.pyw)"))
        if fileName:
            file = QFile(fileName)
            if not (file.open(QIODevice.ReadOnly)):
                QMessageBox.critical(self,
                                     self.tr("Error"),
                                     self.tr("Could not open file."))
                return
            inFile = QTextStream(file)
            self._textEdit.setText(inFile.readAll())
            file.close()


    @pyqtSlot()
    def _save(self):
        fileName = QFileDialog.getSaveFileName(self,
                                               self.tr("Save file"),
                                               '',
                                               self.tr("Text files (*.txt);;Python files (*.py *.pyw)"))
        if fileName:
            file = QFile(fileName)
            if not (file.open(QIODevice.WriteOnly)):
                QMessageBox.critical(self,
                                     self.tr("Error"),
                                     self.tr("Could not write to file."))
                return
            else:
                stream = QTextStream(file)
                stream << self._textEdit.toPlainText()
                stream.flush()
                file.close()


def main():
    app = QApplication(sys.argv)

    notepad = Notepad()
    notepad.show()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()