игра в понг два игрока ошибка tkinter

я пытался выполнить этот код:

import Tkinter as tk
import tkFont
import functools
import math
import random
import time

class Pong(tk.Canvas):

    DEFAULTS = dict(width=640, height=480,background='black',highlightthickness=0)

    def main(cls):
        root = tk.Tk()
        root.title('Pong')
        root.resizable(False, False)
        root.bind_all('<Escape>', lambda event: root.destroy())
        game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
        game.grid()
        root.mainloop()

но у меня были эти ошибки:

Traceback (most recent call last):
   line 413, in <module>
    pong.main()
  , line 17, in main
    game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
AttributeError: Pong instance has no __call__ method

person user3200290    schedule 15.01.2014    source источник
comment
Что такое cls, который вы проходите?   -  person aIKid    schedule 16.01.2014
comment
Можете ли вы показать нам строку 413, где вы вызываете pong.main(), и немного раньше, где вы назначаете pong?   -  person poke    schedule 16.01.2014
comment
если name == 'main': pong = Pong() Pong.main()   -  person user3200290    schedule 16.01.2014
comment
строка 413, в ‹module› Pong.main() TypeError: несвязанный метод main() должен вызываться с экземпляром Pong в качестве первого аргумента (вместо этого ничего не получил)   -  person user3200290    schedule 16.01.2014


Ответы (3)


Я пока вижу одну основную проблему

cls входит в качестве переменной

def main(cls):  

Затем вы используете его как функцию

game = cls(tkFont.Font(family='Book Antiqua', size=15, weight='bold'), 5, 100,background='black', width=640, height=480)
person Aidan    schedule 15.01.2014

Как вы упомянули в комментариях, вот как вы создаете pong и вызываете main:

if __name__ == '__main__':
    pong = Pong()
    pong.main()

В то время, когда вы вызываете Pong(), вы создаете экземпляр. Таким образом, вызываемый вами метод main является методом экземпляра, где первым неявным параметром является сам экземпляр. Обычно этот параметр называется self для методов экземпляра, а не cls, как у вас.

Поэтому, если мы переименуем его, станет ясно, что после этого не работает:

game = self(tkFont.Font(…), 5, 100, background='black', width=640, height=480)

Имейте в виду, что self — это объект и экземпляр Pong. Так что это не функция и не конструктор, который вы можете вызвать; на самом деле вы пытаетесь вызвать экземпляр, который здесь не сработает.

Я думаю, вместо этого вы хотите использовать main как «статический» метод, являющийся точкой входа в ваше приложение. В этом случае вы должны добавить декоратор @classmethod перед объявлением метода:

@classmethod
def main(cls):
    root = tk.Tk()
    # …

В этом случае cls действительно будет типом Pong, который вы сможете вызвать позже для создания объекта Pong.

Однако вам следует изменить часть __name__ == '__main__ только на Pong.main(), так как вы больше не вызываете main для экземпляра, а для всего типа.

if __name__ == '__main__':
    Pong.main()
person poke    schedule 15.01.2014
comment
я сделал то, что вы имеете в виду, и у меня была ошибка: Pong.main() TypeError: несвязанный метод main() должен вызываться с экземпляром Pong в качестве первого аргумента (вместо этого ничего не получил) - person user3200290; 16.01.2014
comment
@user3200290 user3200290 Тогда вы, кажется, забыли добавить строку @classmethod перед def main. - person poke; 16.01.2014
comment
извините, это было потому, что я забыл поставить декоратор, но теперь у меня была эта ошибка: Pong.main() AttributeError: class Pong не имеет атрибута «main» - person user3200290; 16.01.2014
comment
Хм, убедитесь, что ваш отступ все еще правильный, так что функция все еще является частью класса Pong. - person poke; 16.01.2014

Вы делаете очень странную вещь - вы создаете подкласс tk.Canvas, но вы не инициализируете tk до тех пор, пока не создадите этот объект. Это неправильный способ использования tkinter. Вы должны инициализировать Tk за пределами этого класса или не наследовать от tk.Canvas.

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

Например:

import Tkinter as tk

class Pong(tk.Canvas):
    def __init__(self, root):
        tk.Canvas.__init__(self, root)
        <put other "main" code here if you want>

if __name__ == "__main__":
    root = tk.Tk()
    pong = Pong(root)
    pong.pack(fill="both", expand=True)
    root.mainloop()
person Bryan Oakley    schedule 16.01.2014