Monday, January 23, 2012

Qt 4.8 Notepad Tutorial - Part 3

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'
    
    When the user wants to quit an application, you might want to 
    pop-up a dialog that asks whether he/she really wants to quit. 
    In this example, we subclass QWidget, and add a slot that we 
    connect to the Quit button.
    
    NOTES:
    =====
    The original code defines 'textEdit' as a 'private' variable.
    This is simulated here by the underscore in '_textEdit' although
    this is only to signal to other developers that the variable
    is not meant to be accessed by external classes. 
    Python, unlike C++ and Java, does not enforce privacy, as is 
    evident when the 'notepad._textEdit.setText()' method is called in main().
    
    The original code also defines the Quit button variable as private.
    Here it is simply defined as a local variable within the __init__
    method as it is not called by any of the class methods. Neither
    can it be accessed by external methods such as main(); it's scope
    (accessibility) is limited to the __init__ method.
    
    User visible strings are wrapped in the 'self.tr()' function 
    which is provided by QObject, the base class for all Qt objects.
    The function makes the strings accessible to the Qt translation 
    utility 'Qt Linguist'
    
    The 'quit()' method has been renamed 'quit_()' as 'quit' is a
    reserved word in Python. Since the method is being used as a
    'slot' it has been identified as such using a PyQt4 decorator
    which, according to the PyQt4 documentation, will improve
    memory performance.

last modified: 2012-01-23 jg
ref: 
    http://developer.qt.nokia.com/doc/qt-4.8/gettingstartedqt.html
    http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/new_style_signals_slots.html
'''
import sys
from PyQt4.QtGui import (QApplication, QTextEdit, QPushButton, QWidget,
                         QVBoxLayout, QMessageBox)
from PyQt4.QtCore import (pyqtSlot)

class Notepad(QWidget):     # subclass QWidget

    def __init__(self, parent=None):
        super(Notepad, self).__init__(parent)  # initialise base (QWidget) class

        self._textEdit = QTextEdit()
        quitBtn = QPushButton(self.tr("&Quit"))

        # connect the quitBtn to this objects quit() method
        quitBtn.clicked.connect(self.quit_)

        layout = QVBoxLayout()
        layout.addWidget(self._textEdit)
        layout.addWidget(quitBtn)

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

    @pyqtSlot()         # identify this method as a 'slot'
    def quit_(self):
        msgBox = QMessageBox()
        msgBox.setWindowTitle(self.tr("Notepad"))
        msgBox.setText(self.tr("Are you sure you want to quit?"))
        msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        msgBox.setDefaultButton(QMessageBox.No)

        if msgBox.exec() == QMessageBox.Yes:
            QApplication.instance().quit()


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

    notepad = Notepad()
    notepad._textEdit.setText("We now inherit QWidget.")
    notepad.show()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()