Make Pretty GUI Apps Fast with Python-Qt - page 2
A Minimal Window, Signals and Slots
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).
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_()
It looks like Figure 3. Ugly! That won't do!