Magic Counter

**= COMPLETED =**

## About

This is a simple app that lets you keep track of player's life totals when playing a game of Magic: The Gathering.

Git : magic-counter

## Difficulties I faced

A difficult thing initially in this project was trying to remember how to work with PyQt and Qt Designer. As I haven't worked with them in a long time, and getting the UI to look the way I wanted and getting simple connections of buttons working correctly was challenging.

### **Significant Errors**

#### **Error 01**

One of the first major issues I encountered was when running a certain line of code that would alter the text of a label when a certain button was pressed:

In the code above the function takes in a string specifying the player that is being effected by the reduction of life points. If said player is "player02" then we get the text value of the current life points player two has, reduce it by 1, and make the label now have the new text value.
However when running this, when pressing the minus button for player 2 the screen would simply pause a moment and close itself down.

**Solution:** It turned out that the cause of this what seemed like an infinite loop was because I was trying to assign an integer as text to the label. Simply changing :

```
self.ui.PlayerTwoCounter_label.setText(player02Counter)

```

to :

```
self.ui.PlayerTwoCounter_label.setText(str(player02Counter))

```

resolved this issue.

#### **Error 02**

I was having trouble with getting my "Winner" pop-up message to stay on the screen for more than half a second. When a life counter would hit 0 the message box would flash up on the screen quickly and then disapear.
**Solution:** Turns ou the reason for this was because I wasn't keeping a reference to it anywhere, so it would get garbage collected every time the function was returned. THe fix to this was to add a .exec\_() so it would block until the user clicked the close button on the pop-up.

```
def popup(self):
    msgBox = QMessageBox()
    msgBox.setText("Congratulations! ? is the winner!")

    msgBox.show()
    msgBox.exec_()

```

#### **Error 03**

For some reason, when trying to access the self.player02Counter variable in the popup() function, the window errors out similar to what was happening during the Error 01 issue. It pause once the Player 02 counter hit 0, then crash.
Here is the popup function's code:

```
# Shows popup declaring who is the winner and who is the loser.
def popup(self):
    winner = ""

    print("player 02 = %s" % self.player02Counter)

    #Find out who had the lowest health, and therefore find out the winner.
    if int(self.player01Counter) > int(self.player02Counter):
        winner = "Player One"
    else:
        winner = "Player Two"

    msgBox = QMessageBox()
    msgBox.setText("Congratulations! %s is the winner!" % winner)

    msgBox.show()
    msgBox.exec_()

```

It appears to crash once it gets to the if-else statement.
**Solution:** Turns out the issue was that when I was trying to call either self.player02Counter or self.player01Counter, depending on what counter was the one to reach zero, it wasn't finding the variable bacause I did not create it in the class initializer. The variables were being created inside an if-elif statement in the takeLife() function. So to fix this issue I declared the variables in the home() function :

```
# Functions concerning the home page.
def home(self):
    # Setting base life points.
    self.basePoints = "20"
    self.player02Counter = self.basePoints
    self.player01Counter = self.basePoints
    .
    .
    .

```

#### **Error 04**

I am having trouble getting values from a dialog box to carry over to my main window.
What I want to do is be able to open up a settings dialog box, and change the labels containing the player names in the main window.

The way I am trying to do this is inside the AppSettings object (the dialog box), have it check whether the lineEdit has been changed using the *.textChanged* method, storing the text from the lined edit in a variable, then accessing that variable in the function that I used to call the dialog box.
when the line in the openSettings() function tries to print *self.settingsWindow.playerOneName* it always returns "Players One", the default setting that is declared at the initialization of the dialog box.
**Solution:** Turns out the issue was that I :was calling the *.textChanged.connect*on :

```
self.settings.playerOneName_lineEdit.textChanged.connect(self.syncLineEdit)

```

when I should have been calling it on

```
self.playerOneName_lineEdit.textChanged.connect(self.syncLineEdit)

```

leaving out the *.settings* before the *playerOneName\_lineEdit*. Now we are successfully connecting to the syncLineEdit() function whenever anything is added to the lineEdit, and adding this to the openSettings() function for the main window :

```
# Function used for opening up the settings dialog box in the edit menu.
def openSettings(self):
    self.settingsWindow = AppSettings()
    self.settingsWindow.exec_()

    print("New name recieved: %s" % self.settingsWindow.playerOneName)
    self.ui.playerOne_label.setText(str(self.settingsWindow.playerOneName))

```

means that when the dialogue window is closed, the label for playerOne is changed successfully.