April 16, 2014
 
 
RSSRSS feed

Make Pretty GUI Apps Fast with Python-Qt - page 2

A Minimal Window, Signals and Slots

  • January 28, 2010
  • By Akkana Peck

Now let's make a bigger application: a 5-card draw poker game. The beginning is just the same, with the addition of the random module so you can deal cards:

#!/usr/bin/python

from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, random

class PokerWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.mainWidget = QWidget(self) # dummy to contain the layout manager
        self.setCentralWidget(self.mainWidget)
        self.setWindowTitle('Poker')

One difference: the central widget is now a new object named "mainWidget". That's because QMainWindow doesn't give you much control over how objects are laid out in the window. The poker game will be set up as a grid, with the five cards arranged horizontally, ranks and suits vertically (Figure 2).

figure 2
figure 2

Creating a separate widget lets you use a grid layout:

        self.grid = QGridLayout()
        self.mainWidget.setLayout(self.grid)

We'll need five cards, each of which has a rank and a suit. We'll also need a list of the ranks and suits:

        # The five cards: each has a rank and a suit.
        self.ranks      = [None, None, None, None, None]
        self.suits      = [None, None, None, None, None]

        # Possible suits:
        self.suitnames   = ["Diamonds", "Spades", "Hearts", "Clubs"]

        # Possible ranks:
        self.ranknames = [ "1", "2", "3", "4", "5", "6", "7", "8",
                           "9", "10", "J", "Q", "K", "A" ]

It's time to create the widgets to display the cards, using one QLabel object for each card's rank and another for the suit. Each card will occupy a column of its own, with its rank in row 0 and the suit in row 1.

        # Create the labels for the card ranks and suits:
        for i in range(0, len(self.ranks)) :
            self.ranks[i] = QLabel()
            self.grid.addWidget(self.ranks[i], 0, i)

            self.suits[i] = QLabel("")
            self.grid.addWidget(self.suits[i], 1, i)

Finally, two buttons at the bottom: a Quit button, plus a button to deal a new hand.

        # "Deal" button
        self.dealbutton = QPushButton("Deal")
        self.grid.addWidget(self.dealbutton, 2, 0)
        self.connect(self.dealbutton, SIGNAL('clicked()'), self.dealNewHand)

        # Quit button
        quitbutton = QPushButton("Quit")
        self.grid.addWidget(quitbutton, 2, 4)
        self.connect(quitbutton, SIGNAL('clicked()'), self, SLOT('close()'))

Of course you'll need a function to deal random cards. Still inside your PokerWindow class:

    def dealNewHand(self) :
        for i in range(0, 5) :
            rank = random.randint(0, 12);
            self.ranks[i].setText(self.ranknames[rank])

            suit = random.randint(0, 3);
            self.suits[i].setText(self.suitnames[suit])

And some code to run the app:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = PokerWindow()
    win.dealNewHand()
    
    win.show()
    app.exec_()

Run it:

python poker.py

It looks like Figure 3. Ugly! That won't do!

figure 3
figure 3

 

 

Sitemap | Contact Us