Dwight
Dwight

Reputation: 124

Is there a way to update the grid in PySimpleGUI after clicking on it

Good day all,

I have been working on creating a GUI for my Tic Tac Toe game using PySimpleGUI. My code is as follow:

import PySimpleGUI as sg
import random 

board_layout1 = {(2,0):" ", (2,1):" ", (2,2): " ", (1,0): " ", (1,1): " ", (1,2): " ", (0,0): " ", (0,1): " ", (0,2): " "}

Board layout is based on:

Diagram

I then created an interface to take in user input (i.e. name and choosing X or O symbol).

layout = [      
        [sg.Text("Please enter your Name and your opponent's name")],    
        [sg.Text('Name', size=(15, 1)), sg.InputText('')],      
        [sg.Text('Name of opponent', size=(15, 1)), sg.InputText('')],
        [sg.Frame(layout=[
        [sg.Radio('X', "RADIO1", default=True, size=(10,1)), sg.Radio('O', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags')],
        [sg.Submit(), sg.Cancel()]      
        ]

window = sg.Window('Tic Tac Toe Game').Layout(layout)         
button, events = window.Read() 
print(events)
window.close()     


player1, player2, player1_event, player2_event = events[0], events[1], events[2], events[3]

player1 and player2 will return their names. Player1_event and player2_event will return True or False. As I am using a checkbox, events2 will be True if I checked it while events[3] will be False.

I then assign the marker respectively.

if player1_event == True:
    player1_marker, player2_marker = ("X", "O")
else:
    player1_marker, player2_marker = ("O", "X")

Now, I will create the GUI for the board.

def board_gui():    
    max_row = max_col = 3

    layout =  [[sg.Button(' ', size=(8, 4), key=(i,j), pad=(0,0)) for j in range(max_col)] for i in range(max_col)]

    window = sg.Window('Tictactoe', layout)
    button, events = window.Read()
    return button 
    window.close()

Next (where the problem is), I created the function to update the board accordingly. So let's say if play1 starts first and he decided to choose 'X' as his marker. He picked the first grid and click on it. It marks 'X'. So the next click should belong to play2, whose marker is 'O'. My code seems to have issue updating the marker for the second click.

What I did:

def board_gui_update(marker):   
    max_row = max_col = 3

    layout =  [[sg.Button(' ', size=(8, 4), key=(i,j), pad=(0,0)) for j in range(max_col)] for i in range(max_col)]
    window = sg.Window('Tictactoe', layout)
    while True:
        button, events = window.Read()
        if button in (None, 'Exit'):
            break
        window[button].update(marker)

    window.close()

What I have tried:

def board_gui_update(marker):   
    max_row = max_col = 3
    layout =  [[sg.Button(' ', size=(8, 4), key=(i,j), pad=(0,0)) for j in range(max_col)] for i in range(max_col)]
    window = sg.Window('Tictactoe', layout)
    while True:
        button, events = window.Read()
        if button in (None, 'Exit'):
            break
        if marker == player1_marker:
            turn = player1
            if turn == player1:
                window[button].update(player1_marker)
                turn = player2
            else:
                window[button].update(player2_marker)
        else:
            if marker == player2_marker:
                turn = player2
                if turn == player2:
                    window[button].update(player2_marker)
                turn = player1
            else:
                window[button].update(player1_marker)

    window.close()

Doesn't seem to work here as well. I have looked into the documentations and also solutions that involved tkinter but nothing seems to be able to update the marker.

You can view the issue in this snapshot.

Upvotes: 4

Views: 4026

Answers (2)

PedroLucas
PedroLucas

Reputation: 1

Based on the samples above, I made this code wich can alternate between the 'O' and 'X'. I used a variable that alternates between False and True, and two ifs that identifies the values inside window[event].get_text(), analysis it and changes the variable.

import PySimpleGUI as sg

layout = [[sg.Button(' ', size=(8,4)), sg.Button(' ', size=(8,4)), 
           sg.Button(' ', size=(8,4))],
          [sg.Button(' ', size=(8,4)), sg.Button(' ', size=(8,4)), 
           sg.Button(' ', size=(8,4))],
          [sg.Button(' ', size=(8,4)), sg.Button(' ', size=(8,4)), 
           sg.Button(' ', size=(8,4))]]

turn = True
window = sg.Window('Tic Tac Toe', layout)

while True:    # Event Loop
    event, values = window.read()
    print(event, values) #Just for development purposes.
    if event in (None, 'Exit'):
        break
    current_marker = window[event].get_text()
    # I placed all updates conditionals inside this, works better than 
    # individuals 'ifs' for each of they.
    window[event].update('X' if current_marker == ' ' and 
                         turn == True else 'O' if current_marker == ' ' and 
                         turn == False else 'X' if current_marker == 'X' 
                         else 'O' if current_marker == 'O' else ' ') 
    # The conditionals that change which value should be inserted.
    if window[event].get_text() == 'X':
        turn = False                       
    elif window[event].get_text() == 'O':
        turn = True

window.close()

Upvotes: 0

Mike from PSG
Mike from PSG

Reputation: 5754

See if this does what you're after. Every time you click on a square, it will change to a new marker. I think you're saying you cannot change the value shown on the button. This program shows you how to do it.

import PySimpleGUI as sg

layout = [[sg.B(' ', size=(8,4), key=(i,j)) for i in range(3)] for j in range(3)]

window = sg.Window('Tic Skeleton', layout)

while True:             # Event Loop
    event, values = window.read()
    print(event, values)
    if event in (None, 'Exit'):
        break
    current_marker = window[event].get_text()
    window[event].update('X' if current_marker == ' ' else 'O' if current_marker == 'X' else ' ')
window.close()

enter image description here

Upvotes: 1

Related Questions