Any main windowed applications in the GUI are to be supplemented with dialogs and widgets to present a complete workable and usable application to the users. Dialogs are those small sized windows with some specific functions that will aid the users with selecting some options or executing some operations. The most common examples of dialogs include "File Open" dialog and a "Search Dialog" in many text/image editing applications, a "Color Chooser" dialog in various paint applications and so on. In many GUI toolkits, the terms dialogs and widgets are used interchangeably. As a general difference, the dialogs are the small windows whose main purpose is to establish a connection between the user and the program. We normally use dialog boxes to receive an input from the users or to represent an output or error message to the users. However, the widgets are collections of building blocks of the applications such as buttons, checkboxes, progress bars, and so on. This chapter will introduce you to some of the built-in dialogs and widgets that Qt provides us. Moving on, we will develop a customized "Find" dialog that will add to the text editor program which we have developed in third chapter. We will also develop a customized "Analog Clock" widget.
Qt
is provided with a rich set of built-in dialogs. They are as follows:
QFileDialog
: It provides the user with a dialog that allows them to select files or directoriesQErrorMessage
: It provides the user with a dialog that displays error messagesQColorDialog
: It provides the user with a dialog for specifying/choosing between colorsQPrintDialog
: It provides the user with a dialog that aids in printer and printing configurationQPageSetupDialog
: It provides the user with a dialog that manages configuration for the page-related options on a printerQWizard
: It provides a dialog framework for wizardsQProgressDialog
: It provides feedback on the progress of a slow operationQPrintPreviewDialog
: It provides a dialog for previewing and configuring page layouts for printer outputQMessageBox
: It provides a dialog for displaying some information to the userQInputDialog
: It provides a simple convenience dialog to get a single value from the userQFontDialog
: It provides a dialog widget for selecting a fontIn this section, we would discuss the implementations of some widely used widgets. A few of the widgets like, QMessageBox
, QFontDialog
, and QErrorMessage
have already been introduced to you in some of the preceding chapters.
The PySide.QtGui.QFileDialog
class provides a dialog that allows users to select files or directories. It helps users to traverse the native file system in order to select one or many files or directory. The easy and best way to create a file dialog is to use the static functions provided by the QFileDialog
class. A sample use of static function is as follows:
fileName = QFileDialog.getOpenFileName(self, "Open Files", "c:/", "Textfiles(*.txt)")
In this example, the file dialog was created using a static function getOpenFileName
. Initially, this function call will create a file dialog with the path mentioned in the third parameter of the function. The fourth parameter restricts the type of files that has to be shown in the dialog for opening. The first parameter takes the value of the parent to the dialog and the second is used to display a title for the dialog. The filters that are represented in the fourth parameter can take multiple values depending on the type of files that are to be filtered. Please note that the values must be separated by a delimiter ";". An example for the filter can look like as shown in the following code line.
"Images (*.png *.jpg);; Text files (*.txt);; Word documents(*.doc)"
The following code shows an example for creating the "File" dialog as a menu option. The program is self-explanatory and is based on the concepts that we have seen in the third chapter of this book.
import sys from PySide.QtGui import * class MyFileDialog(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.textEdit = QTextEdit() self.setCentralWidget(self.textEdit) self.statusBar() openFile = QAction(QIcon('open.png'), 'Open', self) openFile.setShortcut('Ctrl+O') openFile.setStatusTip('Open new File') openFile.triggered.connect(self.showDialog) menubar = self.menuBar() fileMenu = menubar.addMenu('&File') fileMenu.addAction(openFile) self.setGeometry(300, 300, 350, 300) self.setWindowTitle('Example - File Dialog') self.show() def showDialog(self): fileName, _ = QFileDialog.getOpenFileName(self, "Open Text Files", "c:/", "Text files(*.txt)") contents = open(fileName, 'r') with contents: data = contents.read() self.textEdit.setText(data) if __name__ =='__main__': # Exception Handling try: myApp = QApplication(sys.argv) myFD = MyFileDialog() myFD.show() myApp.exec_() sys.exit(0) except NameError: print("Name Error:", sys.exc_info()[1]) except SystemExit: print("Closing Window...") except Exception: print(sys.exc_info()[1])
If you run this program, you could witness a file open dialog is opened on triggering the File | Open option in the menu bar.
The file dialog can also be created without using the static functions by directly creating an instance of the QFileDialog
class as explained in the following code snippet:
fileDialog = QFileDialog(self) fileDialog.setFileMode(QFileDialog.AnyFile) fileDialog.setNameFilter("Text files(*.txt)")
The second line of the preceding code sets the mode of the file dialog to AnyFile
, which means that the user can specify a file that doesn't even exist in the file system. This mode is highly useful when we want to create a "Save As" dialog. The other modes that the file dialog can take are:
The third line depicts how to set the filters for the file dialog as explained in the previous program. Also, the file dialog has two view modes, namely, View and Detail, where the latter being the default mode. As the name indicates, the list view just displays the name of the files and directories in a list but the detail mode enhances it with additional details about the file such as, file size, date modified, and so on.
The PySide.QtGui.QInputDialog
class provide a very easy and convenient dialog to receive input from the users. The input can be a text string, a number or an item from the list. A label is provided with the input box to indicate the user what they have to enter. To enable this, four convenient functions are used:
QInputDialog.getText()
: It receives a text or string from the userQInputDialog.getInteger()
: It receives an integer value as an inputQInputDialog.getDouble()
: It receives a float value as input with double precision accuracyQInputDialog.getItem()
: It receives a particular selectable value from the list of itemsThe dialog is provided with two buttons OK and Cancel to accept or reject values respectively as shown in the following screenshot:
The following code explains the use of various input dialogs:
# Import necessary modules import sys from PySide.QtGui import * class MyInputDialog(QWidget): def __init__(self): QWidget.__init__(self) self.myNameButton = QPushButton('Name', self) self.myNameButton.clicked.connect(self.showNameDialog) self.myAgeButton = QPushButton('Age', self) self.myAgeButton.clicked.connect(self.showAgeDialog) self.myChoiceButton = QPushButton('Choice', self) self.myChoiceButton.clicked.connect(self.showChoiceDialog) self.myNameLE = QLineEdit(self) self.myAgeLE = QLineEdit(self) self.myChoiceLE = QLineEdit(self) self.myLayout = QFormLayout() self.myLayout.addRow(self.myNameButton, self.myNameLE) self.myLayout.addRow(self.myAgeButton, self.myAgeLE) self.myLayout.addRow(self.myChoiceButton, self.myChoiceLE) self.setLayout(self.myLayout) self.setGeometry(300, 300, 290, 150) self.setWindowTitle('Input Dialog Example') self.show() def showNameDialog(self): text, ok = QInputDialog.getText(self, 'Input Text Dialog', 'Enter your name:') if ok: self.myNameLE.setText(str(text)) def showAgeDialog(self): text, ok = QInputDialog.getInteger(self, 'Input Number Dialog', 'Enter your age:') if ok: self.myAgeLE.setText(str(text)) def showChoiceDialog(self): strList = ['Ice Cream', 'Chocolates', 'Milk Shakes'] text, ok = QInputDialog.getItem(self, 'Input Combo Dialog', 'Enter your choice:', strList) if ok: self.myChoiceLE.setText(str(text)) if __name__ =='__main__': # Exception Handling try: myApp = QApplication(sys.argv) myID = MyInputDialog() myID.show() myApp.exec_() sys.exit(0) except NameError: print("Name Error:", sys.exc_info()[1]) except SystemExit: print("Closing Window...") except Exception: print(sys.exc_info()[1])
In the preceding code, each button click event is connected to a slot that presents the user with different input dialogs. The values of the dialogs reflect on the line edit box after clicking on the OK button. A sample output of the preceding program is given in the following screenshot for your reference:
The PySide.QtGui.QColorDialog
class provides a dialog for choosing and specifying colors. The color dialog is mainly used in the paint applications to allow the user to set the color of the brush or paint an area with a specific color. This dialog can also be used to set text colors in text based applications. As with the other dialogs, we use a static function QColorDialog.getColor()
to show the dialog and subsequently allow the user to select a color from the dialog. This dialog can also be used to allow the users to select the color transparency by passing some additional parameters. It is also possible to set and remember the custom colors and share them between color dialogs in an application. The following code is a short example of using the color dialog:
# Import necessary modules import sys from PySide.QtGui import * class MyColorDialog(QWidget): def __init__(self): QWidget.__init__(self) myColor = QColor(0, 0, 0) self.myButton = QPushButton('Press to Change Color', self) self.myButton.move(10, 50) self.myButton.clicked.connect(self.showColorDialog) self.myFrame = QFrame(self) self.myFrame.setStyleSheet("QWidget { background-color: %s }" % myColor.name()) self.myFrame.setGeometry(130, 22, 100, 100) self.setGeometry(300, 300, 250, 180) self.setWindowTitle('Color Dialog - Example') self.show() def showColorDialog(self): color = QColorDialog.getColor() if color.isValid(): self.myFrame.setStyleSheet("QWidget { background-color: %s }" % color.name()) if __name__ =='__main__': # Exception Handling try: myApp = QApplication(sys.argv) myCD = MyColorDialog() myCD.show() myApp.exec_() sys.exit(0) except NameError: print("Name Error:", sys.exc_info()[1]) except SystemExit: print("Closing Window...") except Exception: print(sys.exc_info()[1])
The preceding example will show a button, which when clicked shows a color dialog. The colour can be selected and the same is painted in the frame used for this purpose.
The PySide.QtGui.QPrintDialog
class provides a dialog for specifying the user's printer configuration. The configuration include document-related settings, such as the paper-size and orientation, type of print, color or grayscale, range of pages, and number of copies to print. The configuration settings also allows the user to select the type of printer from the printers available, including any configured network printers. The QPrintDialog
objects are constructed with a PySide.QtGui.QPrinter
object and executed using the exec_()
function. The printer dialog uses the native system of display and configuration. The following example shows a crude way of creating a print dialog. The refined implementation is left as an exercise for you to explore. A sample implementation can be downloaded from the code snippets that come along with this book.
def printDoc(self): document = QTextDocument("Sample Page") printer = QPrinter() myPrintDialog = QPrintDialog(printer, self) if myPrintDialog.exec_() != QDialog.Accepted: return document.print_(printer)