Есть ли способ обновить сетку в PySimple GUI после нажатия на нее - PullRequest
4 голосов
/ 22 февраля 2020

Добрый день всем,

Я работаю над созданием GUI для моей игры Ti c Ta c Toe с использованием PySimple GUI. Мой код выглядит следующим образом:

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

Теперь я создам GUI для доски.

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, но, похоже, ничто не может обновить маркер.

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

Ответы [ 2 ]

1 голос
/ 23 февраля 2020

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

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

0 голосов
/ 29 марта 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()
...