เกมปิงปอง ผู้เล่นสองคนเกิดข้อผิดพลาด 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
ถ้า ชื่อ == 'main': pong = Pong() Pong.main()   -  person user3200290    schedule 16.01.2014
comment
บรรทัด 413 ใน ‹module› Pong.main() TypeError: unbound method main() จะต้องถูกเรียกพร้อมกับ Pong instance เป็นอาร์กิวเมนต์แรก (ไม่มีอะไรแทน)   -  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 ดูเหมือนคุณจะลืมเพิ่มบรรทัด @classmethod หน้า def main - person poke; 16.01.2014
comment
ฉันขอโทษ นั่นเป็นเพราะฉันลืมใส่มัณฑนากร แต่ตอนนี้ฉันมีข้อผิดพลาดนี้: Pong.main() AttributeError: class Pong has no คุณลักษณะ '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