1
\$\begingroup\$
from random import randint
from time import sleep
from sys import (exit, argv)
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QToolTip, QPushButton, QApplication, QWidget, QLabel)
from PyQt5.QtGui import (QIcon, QPixmap, QFont)

#Creates the main widget which will contain everything else
class coinflipsimulator(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        #Creates the QLabel 'coin' which will contain the image of the coin
        self.coin = QLabel(self)
        #Uses QPixmap to place a random coin image (head or tail) into the QLabel 'coin'
        self.coin.setPixmap(QPixmap('coin_' + str(randint(1, 2)) + '.png').scaled(162, 302, Qt.KeepAspectRatio, Qt.FastTransformation))
        self.coin.move(0.5, 0.5)

        #Creates the button that will activate the simulated coin flip when clicked and labels it 'Flip' using QPushButton
        self.btn = QPushButton('Flip', self)
        #Selects the font/font size for the label on the QPushButton 'btn' using QFont
        self.btn.setFont(QFont('SansSerif', 20))
        #Creates a tooltip when user hovers over the QPushButton 'btn' using QToolTip
        self.btn.setToolTip('Click to Flip Coin')
        #Selects the font/font size for the QToolTip above on the QPushButton 'btn' using QFont
        QToolTip.setFont(QFont('SansSerif', 10))
        #Connects the QPushButton 'btn' to the function 'flipcoin' to activate when the button is clicked
        self.btn.clicked.connect(self.flipcoin)
        self.btn.resize(166, 43)
        self.btn.move(-2, 161)

        #Sets where on the screen the window will open and the size of the window respectively using x and y coordinates
        self.setGeometry(1427, 30, 162, 201)
        #Locks the size of the window and make it impossible for the user to change it
        self.setFixedSize(self.size())
        self.setWindowTitle('Coin Flip Simulator')
        #Sets the window icon to the image file 'icon.png' located in the same folder as the source file
        self.setWindowIcon(QIcon('icon.png'))      
        self.show()

    def flipcoin(self):
        #Sets the image inside the Qlabel 'coin' to a coin flipping animation...aspect ratio is ignored to get the animation to fit inside the window correctly 
        self.coin.setPixmap(QPixmap('coin_flipping_animation.png').scaled(162, 302, Qt.KeepAspectRatio, Qt.FastTransformation))
        #Processes any change made to the program/window in this case the change of the image in the Qlabel 'coin'
        QApplication.processEvents()
        #Pauses the execution of any more code for 0.5 seconds
        sleep(0.5)
        #Sets the image inside the QLabel 'coin' to a random coin image (head or tail) into the QLabel 'coin'
        self.coin.setPixmap(QPixmap('coin_' + str(randint(1, 2)) + '.png').scaled(162, 302, Qt.KeepAspectRatio, Qt.FastTransformation))
        #Processes the second change to the QLabel 'dice'
        QApplication.processEvents()



if __name__ == '__main__':

    #Begins the execution of the QApplication

    app = QApplication(argv)
    ex = coinflipsimulator()
    ex.show()
    exit(app.exec_())  

This is the first GUI I have completed since I started learning to code. It is a simple program which simulates a die roll when the user clicks a button. I am quite proud of myself even though I know it's nothing great still I am always open to advice and suggestions.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Nice program, so only some tips:


First of all, you comments are very useful for you as a beginner but without them your code is much nicer:

class coinflipsimulator(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.coin = QLabel(self)
        self.coin.setPixmap(QPixmap('coin_' + str(randint(1, 2)) + '.png').scaled(162, 302, Qt.KeepAspectRatio, Qt.FastTransformation))
        self.coin.move(0.5, 0.5)

        self.btn = QPushButton('Flip', self)
        self.btn.setFont(QFont('SansSerif', 20))
        self.btn.setToolTip('Click to Flip Coin')
        QToolTip.setFont(QFont('SansSerif', 10))
        self.btn.clicked.connect(self.flipcoin)
        self.btn.resize(166, 43)
        self.btn.move(-2, 161)

        self.setGeometry(1427, 30, 162, 201)
        self.setFixedSize(self.size())
        self.setWindowTitle('Coin Flip Simulator')
        self.setWindowIcon(QIcon('icon.png'))      
        self.show()

    def flipcoin(self):
        self.coin.setPixmap(QPixmap('coin_flipping_animation.png').scaled(162, 302, Qt.KeepAspectRatio, Qt.FastTransformation))
        QApplication.processEvents()
        sleep(0.5)
        self.coin.setPixmap(QPixmap('coin_' + str(randint(1, 2)) + '.png').scaled(162, 302, Qt.KeepAspectRatio, Qt.FastTransformation))
        QApplication.processEvents()



if __name__ == '__main__':

    app = QApplication(argv)
    ex = coinflipsimulator()
    ex.show()
    exit(app.exec_())

Follow the DRY principle (Don't Repeat Yourself). In your code is 2 times the same statement

self.coin.setPixmap(QPixmap('coin_' + str(randint(1, 2)) + '.png').scaled(162, 302, Qt.KeepAspectRatio, Qt.FastTransformation))

In them you repeatedly construct one of two picture names:

coin_1.png
coin_2.png

Why not create a list or a tuple of them, e. g.

COINS = ('coin1.png', 'coin_2.png')

(note the use of uppercase letters for its name as a signal that it will not change) and instead of the

randint(1, 2)

use

choice(COINS)

Or - even better - create the list or tuple of 2 QPixmap objects and apply the choice() function on it?


Hard-coded file names (as the 2 mentioned above) are spread in your code so it will be more difficult to search for them in the case for the need of change them.

What about give all of them (together with other constants) appropriate names near the start of your, e. g.

ICON = 'icon.png'
SLEEP_TIME = .5

and then use those names?


You may even create constants for parameter lists of functions / methods - as you use the same again and again - and then use them, e. g.

SCALED_PARMS = 162, 302, Qt.KeepAspectRatio, Qt.FastTransformation

and then use them in the form

.scaled(*SCALED_PARMS)     # This is only the part of your command

(note the asterisk (*) in front of them for unpacking the ones).

\$\endgroup\$
1
  • \$\begingroup\$ Thank you very much. I'll try what you've recommended. : ) \$\endgroup\$
    – DaveyH-cks
    Commented Aug 8, 2017 at 10:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.