Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

PySideSimplicissimus Module 5 Combine

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

English [French] Japanese

Combine - Licence, About and Close

In this script we shall combine the three previous mini-scripts to one mini-program, which we name combine. All the required material, including listing of sources, is available for download in tuts4pyside. All current source code for "Close", "About", "Show Licence", all versions of "Combined", "Engineering Application" aka "truss" are stored in one repository tuts4pyside. For your convenience, please install a copy of the repository with the following command:

 git clone https://github.com/OldAl/tuts4pyside

If you do not have git, pllease install it first. The first task is to use Qt Designer to design a form and save it in a combine.ui file. This time, we add to the menu bar a File item with sub-tems Show CCPL, About and Close. Qt Designer has a Signal/Slot Editor connecting tool. There we select from the drop-down menus Sender: action_Close, Signal: triggered, Receiver: MainWindow and Slot: close().

In Qt parlance, various clicks or other actions cause signals which need to be connected to the action we want to associate with the signal. The location where the signal is received is called slot. For GUI design, we usually use the provided standard signals. One such fairly general signal is triggered.

The signals are connected to slots and with PySide it can be any Python method, though in our example it is a reaction to it by the MainWindow, which closes, thus terminating the program.

The form is saved as combine.ui. This needs to be converted to the Python readable format as follows:

pyside-uic combine.ui > ui_combine.py

The ui_combine.py can be read by Python and is reasonably understandable for us, humans as well. It is instructive to see this program in action, so we give its listing.

#!/usr/bin/env python
# combine.py - combination of ShowGPL, About, Close scripts

import sys
import platform

import PySide
from PySide.QtGui import QApplication, QMainWindow, QTextEdit, QPushButton, QMessageBox

__version__ = '0.0.1'

from ui_combine import Ui_MainWindow

class MainWindow(QMainWindow, Ui_MainWindow):
 def __init__(self, parent=None):
 super(MainWindow, self).__init__(parent)
 self.setupUi(self)

if __name__ == '__main__':
 app = QApplication(sys.argv)
 frame = MainWindow()
 frame.show()
 app.exec_()

The code of this program is about 15 lines only and most are a kind of standard, which we will reuse again and again. It is useful and instructive to run this program and make sure that it looks OK. We can test triggering all menu items, but only one, namely Close item is functional. For all others we need to provide appropriate code and that is our next step:

#!/usr/bin/env python
# combine.py - combination of ShowGPL, About, Close scripts
# Copyright note omitted.

import sys
import platform

import PySide
from PySide.QtGui import QApplication, QMainWindow, QTextEdit, QPushButton, QMessageBox

__version__ = '0.0.2'
from ui_combine import Ui_MainWindow

class MainWindow(QMainWindow, Ui_MainWindow):
 def __init__(self, parent=None):
 super(MainWindow, self).__init__(parent)
 self.setupUi(self)
 self.actionShow_GPL.triggered.connect(self.showGPL)
 self.action_About.triggered.connect(self.about)

def showGPL(self):
 '''Read and display GPL licence.'''
 self.textEdit.setText(open('COPYING.txt').read())

def about(self):
 '''Popup a box with about message.'''
 QMessageBox.about(self, "About PyQt, Platform and the like",
 """<b> About this program </b> v %s
 <p>Copyright &copy; 2010 Joe Bloggs.
 All rights reserved in accordance with
 GPL v2 or later - NO WARRANTIES!
 <p>This application can be used for
 displaying OS and platform details.
 <p>Python %s - PySide version %s - Qt version %s on s"""  (__version__, platform.python_version(), PySide.__version__, PySide.QtCore.__version__, platform.system()))

if __name__ == '__main__':
 app = QApplication(sys.argv)
 frame = MainWindow()
 frame.show()
 app.exec_()

We simply added the methods about and showGPL and connected them to the signals with the two statements:

 self.actionShow_GPL.triggered.connect(self.showGPL)
 self.action_About.triggered.connect(self.about)

Our program is now fully functional and we could congratulate ourselves and move to some other task. But our GUI does not look great, because most GUIs have alternative ways to achieve the tasks of menu items, buttons or tool bar with icons that cause the appropriate action. Also when the mouse pointer moves over one of the icons it is nice to show a hint of what the icon stands for and also show a message on the task bar that the MainWindow provides by default at the bottom of the form.

Our next task is to provide those facilities.

In this part of the tutorial, we will tackle the method to provide tool bar with enabled icons as well as tip point and status bar hints. First we need some icons. We do not believe in reinventing the wheel, so let us use some readily available set of icons. Our choice is a free "tango icon set".

It is a fairly large collection of icons that the its authors have put out free of any licence restrictions. It should more than cover our requirements. It is convenient to put the selected icons in a small library which we call tango_select. Analogous to combine.ui file from Qt Designer, with a plain text editor (Notepad in windows, kate in KDE, gedit in Gnome) we make up a resource source file combine.qrc. Though it is "black magic XML" it has a simple format that can be copied and modified with ease. Let us look at the listing of it:

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="quit.png">select_tango/32x32/actions/system-log-out.png</file>
<file alias="about.png">select_tango/32x32/apps/preferences-system-session.png</file>
<file alias="showgpl.png">select_tango/32x32/apps/help-browser.png</file>
</qresource>
</RCC>

For example, the icon for quit action will be referred to in the program by its alias quit.png. This will use from tango collection system-log-out.png icon. (We hope you have downloaded the free source of tango. If so, you should substitute *tango for "select_tango" in the "magic" file combine.qrc. Now, similarly to combine.ui, we compile the file to ui_combine.py as follows:

 pyside-rcc combine.qrc -o qrc_combine.py
  • Note: pyside-rcc generates code for Python v2.x by default. If you're developing with Python v3.x, make sure to use the option -py3 or you will get errors.
 pyside-rcc -py3 combine.qrc -o qrc_combine.py

The qrc_combine.py file is simply imported in to the program as shown in the listing.

#!/usr/bin/env python
# combine.py- combination of ShowGPL, About, Close scripts

# Copyright notice removed to save space. 

import sys
import platform

import PySide
from PySide.QtGui import QApplication, QMainWindow, QTextEdit, QPushButton, QMessageBox, QIcon

__version__ = '0.0.3'
from ui_combine import Ui_MainWindow
import qrc_combine

class MainWindow(QMainWindow, Ui_MainWindow):
 def __init__(self, parent=None):
 super(MainWindow, self).__init__(parent)
 self.setupUi(self)
 self.actionShow_GPL.triggered.connect(self.showGPL)
 self.action_About.triggered.connect(self.about)
 iconToolBar = self.addToolBar("iconBar.png")
#——————————————————
# Add icons to appear in tool bar - step 1
 self.actionShow_GPL.setIcon(QIcon(":/showgpl.png"))
 self.action_About.setIcon(QIcon(":/about.png"))
 self.action_Close.setIcon(QIcon(":/quit.png"))
#——————————————————
# Show a tip on the Status Bar - step 2
 self.actionShow_GPL.setStatusTip("Show GPL Licence")
 self.action_About.setStatusTip("Pop up the About dialog.")
 self.action_Close.setStatusTip("Close the program.")
#——————————————————
 iconToolBar.addAction(self.actionShow_GPL)
 iconToolBar.addAction(self.action_About)
 iconToolBar.addAction(self.action_Close)

def showGPL(self):
 '''Read and display GPL licence.'''
 self.textEdit.setText(open('COPYING.txt').read())

def about(self):
 '''Popup a box with about message.'''
 QMessageBox.about(self, "About PyQt, Platform and the like",
 """<b> About this program </b> v %s
 <p>Copyright &copy; 2010 Joe Bloggs.
 All rights reserved in accordance with
 GPL v2 or later - NO WARRANTIES!
 <p>This application can be used for
 displaying OS and platform details.
 <p>Python %s - PySide version %s - Qt version %s on s"""  (''version'', platform.python_version(), PySide.''version'', PySide.QtCore.''version'', platform.system()))

if __name__ == '__main__':
 app = QApplication(sys.argv)
 frame = MainWindow()
 frame.show()
 app.exec_()

Icon images are added to the actions in the program part, marked as step 1

#——————————————————
# Add icons to appear in tool bar - step 1
 self.actionShow_GPL.setIcon(QIcon(":/showgpl.png"))
 self.action_About.setIcon(QIcon(":/about.png"))
 self.action_Close.setIcon(QIcon(":/quit.png"))
#——————————————————

Similarly, the hint texts are added to the program in step 2:

#——————————————————
# Show a tip on the Status Bar - step 2
 self.actionShow_GPL.setStatusTip("Show GPL Licence")
 self.action_About.setStatusTip("Pop up the About dialog.")
 self.action_Close.setStatusTip("Close the program.")
#——————————————————

"One image is worth a thousand words", according to an old proverb of an old culture. The finished combine.py shows the gui, stored in an external repository:

  • combine-v0.0.3.png

It is instructive to remove both step 1 and step 2 code and run the program to observe its behaviour. Then put back step 1 and run the program again and observe. After a while re-introduce step 2. With both steps 1 and 2 removed, there are no icons and the gui looks rather plain:

  • combine-v0.0.3-noIcons.png

A hint: to remove, simply comment the lines by adding "hash" character in column 1 and remove the hash later as required.

Main requirement: enjoy!

Heard in a tutorial class: A lecturer explained to a complaining mother of a first year student: Your son simply is not intelligent enough to complete this course. I explained to him PySide once; I explained to him a second time; I explained it all in even greater detail the third time. Even I understood PySide then, but your son still did not understand it!

I hope even I now understand better how to program GUI in Pyside :)

Return to PySideSimplicissimus