Обновление текстового поля на холсте tkinter

Впервые я создал графический интерфейс, используя tkinter в Python. Я работал с wxPython, и у меня не было такой проблемы, но я никогда не использовал холст. Мыслительный процесс, лежащий в основе холста, заключается в том, чтобы в конечном итоге добавить анимацию. Я создал макет сетки, в котором одна из сеток является холстом. Я пытаюсь обновить поле оценки с помощью itemconfig, но мне не удалось обновить два поля оценки на холсте. Мой код ниже. Любые рекомендации о том, как обновить две оценки на холсте? Я хочу, чтобы старая оценка была удалена до того, как новая оценка будет записана на экран. Спасибо, что посмотрели. Простите глобальные переменные, они должны быть удалены по мере продвижения.

class Gui(Frame):
def __init__(self, root):
    self.root=root
    self.initUI()

def initUI(self):
    global score1, score2   # these are ints
    score1str = str(score1)
    score2str = str(score2)

    root.title("Table Tennis Scoreboard")

    self.canvas = Canvas(root, width=640, height=480, background='green')
    self.canvas.grid(row=0,column=1)

    self.canvas.create_text(185, 90, anchor=W, font=('Calibri', 20),
                                             text="Let's play Table Tennis!")

    self.canvas.create_rectangle(75, 120, 275, 320, outline="red", fill="red")
    self.canvas.create_rectangle(370, 120, 565, 320, outline="blue", fill="blue")

    self.canvas.create_text(125, 130, anchor=W, font=('Calibri', 20),
                                             text="Player 1")
    self.canvas.create_text(425, 130, anchor=W, font=('Calibri', 20),
                                             text="Player 2")

    self.score1_id = self.canvas.create_text(135, 250, anchor=W, font=('Arial', 100),
                                             text=score1str)
    self.score2_id = self.canvas.create_text(435, 250, anchor=W, font=('Arial', 100),
                                             text=score2str)

    frame = Frame(self.root, relief=RAISED, borderwidth=2, background='white')
    frame.grid(row=0,column=0)

    p1up = Button(frame,text="Player1 +1", height=2, width=10, background='red', command=self.add('one'))
    p1up.grid(row = 0,column = 0, padx=10, pady=(20,5))
    p1down = Button(frame,text="Player1 -1", height=2, width=10, background='red', command=self.subtract('one'))
    p1down.grid(row = 1,column = 0, padx=10, pady=(5,100))
    p2up = Button(frame,text="Player2 +1", height=2, width=10, background='blue', command=self.add('two'))
    p2up.grid(row = 3,column = 0, padx=10, pady=5)
    p2down = Button(frame,text="Player2 -1", height=2, width=10, background='blue', command=self.subtract('two'))
    p2down.grid(row = 4,column = 0, padx=10, pady=(5,100))
    reset = Button(frame,text="Reset", height=2, width=10, command=self.new_game())
    reset.grid(row = 6,column = 0, padx=10, pady=(5,20))

def new_game(self):
    global score1, score2   # these are ints
    score1 = 0
    score2 = 0
    self.update_score()

def add(self, player):
    global score1, score2  # these are ints
    self.player = player
    if self.player == 'one':
        #if score1 < 11:
        score1 += 1
    elif self.player == 'two':
        #if score2 < 11:
        score2 += 1
    self.update_score()
    return

def subtract(self, player):
    global score1, score2  # these are ints
    self.player = player
    if self.player == 'one':
        if score1 > 0:
            score1 = score1 - 1
    elif self.player == 'two':
        if score2 > 0:
            score2 -= 1
    self.update_score()
    return

def update_score(self):
    global score1, score2   # these are ints

    score1str = str(score1)
    score2str = str(score2)

    self.canvas.itemconfig(self.score1_id, text=score1str)
    self.canvas.itemconfig(self.score2_id, text=score2str)

    return

if __name__== '__main__':
    root=Tk()
    gui=Gui(root)
    root.mainloop()

person Sherd    schedule 17.12.2014    source источник
comment
Что значит не повезло? Вы получаете сообщение об ошибке? Программа вылетает? Появляются ли неправильные слова?   -  person Bryan Oakley    schedule 18.12.2014
comment
Вы удаляете элемент холста, то есть текст, а затем выполняете оператор create_text с новым текстом. Взгляните на пример удаления на странице effbot.org/tkinterbook/canvas.htm.   -  person    schedule 18.12.2014
comment
Не повезло в том, что баллы не обновляются. Программа загружается, и интерфейс выглядит нормально, хотя и в зачаточном состоянии. Что я хочу, так это то, что я нажимаю кнопку, и счет обновляется. Я попытался удалить поля с холста и создать их заново, но все, что происходит, это то, что отображается ноль, и независимо от того, какую кнопку я нажимаю, счет никогда не меняется после первой загрузки.   -  person Sherd    schedule 18.12.2014


Ответы (1)


Проблема в том, что вы не назначаете функции кнопкам, а возвращаете значения вызовов функций. Например:

  reset = Button(frame,text="Reset", height=2, width=10, command=self.new_game())

Назначает None команде, потому что это то, что возвращает self.new_game(). Вы должны изменить это на:

  reset = Button(frame,text="Reset", height=2, width=10, command=self.new_game)

Что присваивает команде кнопки функцию self.new_game вместо None.

Затем для других кнопок, чтобы передать аргумент команде кнопки, вы должны использовать лямбда-функцию, например:

 p1up = Button(frame,text="Player1 +1", height=2, width=10, background='red', command=lambda: self.add('one'))

Это назначает анонимную функцию, которая вызывает self.add('one') команде кнопки.

Также см.: Почему команда параметра Button выполняется при объявлении?

person fhdrsdg    schedule 18.12.2014
comment
Конечно. wxPython — то же самое. Я только что пришел с кодирования некоторых страниц Javascript в конце дня и полностью пропустил это. Работал как шарм! Спасибо! - person Sherd; 18.12.2014