Improving Our Four Images Program

Introduction

Earlier this week we wrote a program to display four images in a box layout. The code for that program looks something like this:

import sys
from PyQt4 import QtGui, QtCore

# **************************************************
class FourImages(QtGui.QWidget):

	# **************************************************
	def __init__(self):
		super(FourImages, self).__init__()

		self.initUI()

	# **************************************************
	def initUI(self):      

		vbox = QtGui.QVBoxLayout()

		# Row One
		hbox1 = QtGui.QHBoxLayout()

		pixmap1 = QtGui.QPixmap("redrock.png")
		lbl1 = QtGui.QLabel(self)
		lbl1.setPixmap(pixmap1)
		hbox1.addWidget(lbl1)

		pixmap2 = QtGui.QPixmap("73.png")
		lbl2 = QtGui.QLabel(self)
		lbl2.setPixmap(pixmap2)
		hbox1.addWidget(lbl2)

		vbox.addLayout(hbox1)

		# Row Two
		hbox2 = QtGui.QHBoxLayout()

		pixmap3 = QtGui.QPixmap("basketball.png")
		lbl3 = QtGui.QLabel(self)
		lbl3.setPixmap(pixmap3)
		hbox2.addWidget(lbl3)

		pixmap4 = QtGui.QPixmap("functions-4.png")
		lbl4 = QtGui.QLabel(self)
		lbl4.setPixmap(pixmap4)
		hbox2.addWidget(lbl4)

		vbox.addLayout(hbox2)

		# Other Window Setup
		self.setLayout(vbox)
		self.setWindowTitle('Four Images')
		self.show()        

# **************************************************
def main():

	app = QtGui.QApplication(sys.argv)
	ex = FourImages()
	sys.exit(app.exec_())

# **************************************************
if __name__ == '__main__':
    main()

Today, we are going to add some interactivity to the program. We’ll create a program that displays four random images in the window and then each time an imaged is clicked with the mouse, another random image will be displayed in its place.

There is one problem. QLabel does not emit a “clicked” signal. (You can read more about this issue here.) So we’ll first introduce a new programmer created class named ExtendedQLabel that will accomplish our goal for us. The code for ExtendedQLabel is included below. In it, we simply create a new object that includes a QLabel and also emits a signal when the mouse is released on the QLabel.

# **************************************************
class ExtendedQLabel(QtGui.QLabel):
 	
    def __init__(self, parent):
        QtGui.QLabel.__init__(self, parent)
 
    def mouseReleaseEvent(self, ev):
        self.emit(QtCore.SIGNAL('clicked()'))

This class should be included in your program right after your import statements so the class is available for use later in the program. Instead of creating four QLabel objects to hold our images, we will instead create four ExtendedQLabel objects as shown below:

pixmap1 = QtGui.QPixmap(self.images[randint(0,3)]) #random image
self.lbl1 = ExtendedQLabel(self)
self.lbl1.setPixmap(pixmap1)
self.connect(self.lbl1, QtCore.SIGNAL('clicked()'), self.image1Clicked)
hbox1.addWidget(self.lbl1)

Notice that we connect the ExtendedQLabel named self.lbl1 to the method self.image1Clicked. This method will create a new random image and display it in the label as shown below:

# **************************************************
def image1Clicked(self):
    pixmap = QtGui.QPixmap(self.images[randint(0,3)])
    self.lbl1.setPixmap(pixmap)

As you add more images to your window, you’ll need more of these methods (image2Clicked, … etc).

The Assignment

For this assignment, adapt your existing program that displays the four images to display four random, clickable images in four ExtendedQLabels. Each time an image is clicked, a new random image should be displayed in its place (assuming the random image is not the current image).

My version of the program came out like this:

four-clickable-images

I placed these four images in the N: drive if you would liketo use them. When you get the program working, please submit it with the name yourname-qt-fourclickableimages.py using this submission link.

Extending the Program

After you get the program running, add a feature that will count the number of clicks and display the current value in a 5th QLabel in the window. For fun, see how many clicks it takes for you to get all four images the same. Lowest count wins a special prize 🙂