DaveyH-cks
DaveyH-cks

Reputation: 39

Why is my QPushButton closing the application in PyQt5?

from sys import (exit, argv)
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QToolTip, QPushButton, QApplication, QWidget, QLabel, QLineEdit)
from PyQt5.QtGui import (QIcon, QPixmap, QFont)
from random import choice

#Word list for the words the user will attempt to guess
words = ['Captivity', 'America', 'Europe', 'Federal', 'Gluten', 'Ridiculous', 'Automatic', 'Television', 'Difficult', 'Severe', 'Interesting', 'Indonesia', 'Industrial',
     'Automotive', 'President', 'Terrestrial', 'Academic', 'Comedic', 'Comical', 'Genuine', 'Suitcase', 'Vietnam', 'Achievement', 'Careless', 'Monarchy', 'Monetary', 
     'Quarantine', 'Supernatural', 'Illuminate', 'Optimal', 'Application', 'Scientist', 'Software', 'Hardware', 'Program', 'Colonial', 'Algorithm', 'Intelligent']

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

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

        self.initUI()

    def initUI(self):
        #Creates the QLabel 'background' which will contain the white background
        self.background = QLabel(self)
        #Uses QPixmap to place the background into the QLabel 'background'
        self.background.setPixmap(QPixmap('background.jpg').scaled(201, 352, Qt.IgnoreAspectRatio, Qt.FastTransformation))
        self.background.move(0.5, 0.5)

        #Creates the QLabel 'image' which will contain the image of the hangman
        self.image = QLabel(self)
        number = '1'
        #Uses QPixmap to insert the image of the hangman into the QLabel 'image'
        self.image.setPixmap(QPixmap('hangman_' + number + '.png').scaled(100, 200, Qt.KeepAspectRatio, Qt.FastTransformation))
        self.image.move(60, 0.5)

        #Chooses random word from list 'words'
        word = choice(words)  
        #Creates a blank version of the chosen word 
        blank_word = ''
        for i in word:
            blank_word += '__ '
        blank_word.rstrip()
        guessed_letters = []

        self.blank_word_label = QLabel(blank_word, self)
        self.blank_word_label.setFixedWidth(200)
        self.blank_word_label.move(0,200)
        self.blank_word_label.setAlignment(Qt.AlignCenter)

        self.btn = QPushButton('Check', 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 check if the entered letter is in the word')
        #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 'check_letter' to activate when the button is clicked
        self.btn.clicked.connect(self.check_letter)
        self.btn.resize(102, 43)
        self.btn.move(99, 228)

        self.entered_letter = QLineEdit(self)
        font = self.entered_letter.font()
        font.setPointSize(24)
        self.entered_letter.setFont(font)
        self.entered_letter.setMaxLength(1)
        self.entered_letter.setToolTip('Enter a letter and check if it is in the word')
        self.entered_letter.resize(100, 43)
        self.entered_letter.move(0.5, 228)

        #Sets where on the screen the window will open and the size of the window respectively using x and y coordinates
        self.setGeometry(1390, 30, 200, 270)
        #Locks the size of the window and make it impossible for the user to change it
        self.setFixedSize(self.size())
        self.setWindowTitle('Hangman')
        #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 check_letter(self):
        if self.entered_letter.text() in word:
            guessed_letters.append(self.entered_letter.text())

        else:
            number = int(number)
            number += 1
            number = str(number)
            self.image.setPixmap(QPixmap('hangman_' + number + '.png').scaled(100, 200, Qt.KeepAspectRatio, Qt.FastTransformation))
            QApplication.processEvents()

        blank_word = ''
        for i in word:
            if i in guessed_letters:
                blank_word += i

            else:
                blank_word += '__ '

            blank_word.rstrip()

        self.blank_word_label = QLabel(blank_word, self)
        QApplication.processEvents()



if __name__ == '__main__':

    #Begins the execution of the QApplication

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

This is the Hangman game I am currently working on. It is being created using PyQt5 and Python 3.5 on a Windows 7 32-bit machine. The problem I am having is that when I click the QPushButton 'btn' the application closes and I can't figure out why. It isn't finish and there is a lot of code missing but I think it has what it needs to do what I want it to do but it doesn't work. Any help/advice is welcome. :)

Upvotes: 0

Views: 376

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

The main problem is that the variables you create in a method only exist in that area, for example word only exists in initUI, but you want to use it in check_letter, so that's why your program crashes. I have corrected those errors and besides correcting some of the logic, another error is that you are creating a new QLabel, instead you must update the text.

class hangman(QWidget):

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

        self.initUI()

    def initUI(self):
        #Creates the QLabel 'background' which will contain the white background
        self.background = QLabel(self)
        #Uses QPixmap to place the background into the QLabel 'background'
        self.background.setPixmap(QPixmap('background.jpg').scaled(201, 352, Qt.IgnoreAspectRatio, Qt.FastTransformation))
        self.background.move(0.5, 0.5)

        #Creates the QLabel 'image' which will contain the image of the hangman
        self.image = QLabel(self)
        self.number = 1
        #Uses QPixmap to insert the image of the hangman into the QLabel 'image'
        self.image.setPixmap(QPixmap('hangman_{}.png'.format(self.number)).scaled(100, 200, Qt.KeepAspectRatio, Qt.FastTransformation))
        self.image.move(60, 0.5)
        #Chooses random word from list 'words'
        self.word = choice(words)  

        #Creates a blank version of the chosen word 
        blank_word = '__ '*len(self.word)

        self.guessed_letters = ""

        self.blank_word_label = QLabel(blank_word, self)
        self.blank_word_label.setFixedWidth(200)
        self.blank_word_label.move(0,200)
        self.blank_word_label.setAlignment(Qt.AlignCenter)

        self.btn = QPushButton('Check', 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 check if the entered letter is in the word')
        #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 'check_letter' to activate when the button is clicked
        self.btn.clicked.connect(self.check_letter)
        self.btn.resize(102, 43)
        self.btn.move(99, 228)

        self.entered_letter = QLineEdit(self)
        font = self.entered_letter.font()
        font.setPointSize(24)
        self.entered_letter.setFont(font)
        self.entered_letter.setMaxLength(1)
        self.entered_letter.setToolTip('Enter a letter and check if it is in the word')
        self.entered_letter.resize(100, 43)
        self.entered_letter.move(0.5, 228)

        #Sets where on the screen the window will open and the size of the window respectively using x and y coordinates
        self.setGeometry(1390, 30, 200, 270)
        #Locks the size of the window and make it impossible for the user to change it
        self.setFixedSize(self.size())
        self.setWindowTitle('Hangman')
        #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 check_letter(self):

        if self.entered_letter.text() in self.word:
            self.guessed_letters += self.entered_letter.text()
        else:
            self.number += 1
            self.image.setPixmap(QPixmap('hangman_{}.png'.format(self.number)).scaled(100, 200, Qt.KeepAspectRatio, Qt.FastTransformation))

        blank_word = ''
        for i in self.word:
            if i in self.guessed_letters:
                blank_word += i
            else:
                blank_word += '__ '

        self.blank_word_label.setText(blank_word)

Upvotes: 1

Related Questions