Есть ли способ обновить сетку в PySimpleGUI после нажатия на нее

Доброго времени суток всем,

Я работал над созданием графического интерфейса для моей игры Tic Tac Toe с использованием PySimpleGUI. Мой код выглядит следующим образом:

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): " "}

Макет платы основан на:

Диаграмма

Затем я создал интерфейс для ввода пользовательского ввода (т.е. имени и выбора символа X или O).

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 и player2 вернут свои имена. Player1_event и player2_event вернут True или False. Поскольку я использую флажок, события 2 будут истинными, если я установлю его во время событий [3] будет ложным.

Затем я присваиваю маркер соответственно.

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

Теперь я создам графический интерфейс для платы.

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()

Затем (где проблема) я создал функцию для соответствующего обновления платы. Итак, предположим, если play1 начинается первым, и он решил выбрать «X» в качестве своего маркера. Он выбрал первую сетку и щелкнул по ней. Он помечается знаком «X». Таким образом, следующий щелчок должен принадлежать play2, маркер которого равен «O». Похоже, в моем коде возникла проблема с обновлением маркера для второго щелчка.

Что я сделал:

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()

Что я пробовал:

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()

Кажется, здесь тоже не работает. Я просмотрел документацию, а также решения, связанные с tkinter, но, похоже, ничто не может обновить маркер.

Вы можете просмотреть проблему на этом снимке экрана.


person Dwight    schedule 22.02.2020    source источник
comment
Было бы полезно, если бы вы разместили где-нибудь свой код полностью. Чтобы получить помощь, вы можете зарегистрировать проблему на PySimpleGUI GitHub. Обновление текста на кнопке отлично работает в последний раз. Я не совсем уверен в проблеме, которую вы описываете. Вы говорите, что не можете изменить текст кнопки? Если да, попробуйте создать небольшую программу, чтобы убедиться, что проблема в этом или нет.   -  person Mike from PSG    schedule 23.02.2020
comment
Было бы полезно следовать соглашениям о кодировании в примерах и документации PySimpleGUI. Эта строка кода вводит в заблуждение и неверна - button, events = window.Read (). Он должен читать событие, values ​​= window.Read (). Второй параметр - это не события, это словарь значений из окна. Первый параметр - это событие. Иногда это может быть кнопка, но это могут быть и другие вещи, поэтому обозначение ее как кнопки может сбить с толку.   -  person Mike from PSG    schedule 23.02.2020


Ответы (2)


Посмотрите, делает ли это то, что вам нужно. Каждый раз, когда вы нажимаете на квадрат, он превращается в новый маркер. Я думаю, вы говорите, что не можете изменить значение, указанное на кнопке. Эта программа покажет вам, как это сделать.

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()

введите описание изображения здесь

person Mike from PSG    schedule 22.02.2020
comment
Привет @MikeyB, спасибо за ответ. Я скопировал точный сценарий, предоставленный вами, и все еще сталкиваюсь с той же проблемой. Спасибо за совет, я поменял местами кнопку events = Window.read (), поскольку я рассматривал каждый вывод из сетки как кнопку. Я приму ваш совет не менять его. Я включил [ссылку] (repl.it/repls/NavyApphibitedLevel) в свой код. Спасибо еще раз. - person Dwight; 23.02.2020
comment
Что происходит, когда вы копируете и вставляете предоставленный код, когда вы нажимаете кнопки? Они не меняются как на изображении? Если вам нужна дополнительная поддержка или вы считаете, что есть проблема с PySimpleGUI, опубликуйте проблему на github проекта. PySimpleGUI.com. Проблема с попыткой сделать это здесь заключается в том, что не публикуется важная информация о версиях, ОС и т. Д. Есть форма, которую нужно заполнить, когда вы отправляете сообщение о проблеме, в которой будет собрана необходимая информация. - person Mike from PSG; 23.02.2020
comment
Когда я скопировал приведенный выше код и запустил его на repl.it, он работает нормально. Может быть, есть несоответствие в том, что означает столкновение с одной и той же проблемой. Я все еще в замешательстве. Вот моя программа на repl.it, как и ваша. repl.it/@PySimpleGUI/Buttons - person Mike from PSG; 23.02.2020
comment
Смог запустить ваш код и щелкнуть квадратики, которые изменились на X. Это похоже на логическую проблему в вашем коде, а не на какую-то ошибку в PySimpleGUI. Продолжайте работать над этим. В сочетании с тем фактом, что представленный демонстрационный код работал и мог изменять метки кнопок по своему желанию, означает, что у вас где-то есть ошибка. - person Mike from PSG; 23.02.2020
comment
Приношу извинения за неправильную формулировку, ставшую причиной этого недоразумения. Я ожидал чего-то вроде этой ссылки - person Dwight; 24.02.2020
comment
У вас должно получиться это без проблем. В приведенном выше коде показано, как изменить символы, и вы можете изменить цвета, используя тот же метод обновления. Думаю, я не вижу проблемы. Ваша программа смогла изменить цвет (на черный) и символ на кнопке. Похоже, у вас есть все необходимые вам возможности PySimpleGUI. Дело в том, чтобы заставить их работать вместе с правильной логикой игры. - person Mike from PSG; 24.02.2020

Основываясь на приведенных выше примерах, я создал этот код, который может чередоваться между буквами «O» и «X». Я использовал переменную, которая чередуется между False и True, и два if, которые идентифицируют значения внутри window[event].get_text(), анализируют их и изменяют переменную.

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()
person PedroLucas    schedule 28.03.2020