首页 > 解决方案 > 对象没有属性'tk' - tkinter

问题描述

在下面的代码中是一个问题,我找不到。错误:

AttributeError:“游戏”对象没有属性“tk”

我想这是因为场功能。下面的代码显示了对我的程序很重要的函数。

import tkinter as tkinter
from tkinter import *

# class for the game 
class game(tkinter.Frame):

    def __init__(self):

        # main-window 
        self.root = tkinter.Tk()
        # title 
        self.root.title("TicTacToe")
        # text member
        self.text = tkinter.StringVar()
        self.text.set(" ")
        # config
        self.root.geometry("178x130")
        self.root.resizable(width=0, height=0)
        self.root['bg'] = '#1c6796'
        self.root.iconphoto(True, tkinter.PhotoImage(file=r'C:\Users\nicod\Desktop\TicTacToe\icon.png'))
        # buttons 
        self.singleplayer_button = Button(self.root, text = "Singleplayer", command = self.singleplayer_window, font = 'Times 10 italic')
        self.multiplayer_button = Button(self.root, text = "Multiplayer", command = self.multiplayer_window, font = 'Times 10 italic')
        self.quit_button = Button(self.root, text = "Quit", command = quit, font = 'Times 10 italic')
        self.singleplayer_button.place(x = 48, y = 10)
        self.multiplayer_button.place(x = 51, y = 50)
        self.quit_button.place(x = 70, y = 90)

        self.root.mainloop()

    def quit(self):
        self.root.destroy()

    def field(self):

        # 9 buttons for the field
        self.field1 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field2 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field3 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field4 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field5 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field6 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field7 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field8 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field9 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.back   = tkinter.Button(self, text = 'back', command = quit, font = 'Times 10 italic')

        # display buttons
        self.field1.place(x = 50, y = 10)
        self.field2.place(x = 100, y = 10)
        self.field3.place(x = 150, y =10)
        self.field4.place(x = 50, y = 60)
        self.field5.place(x = 100, y = 60)
        self.field6.place(x = 150, y = 60)
        self.field7.place(x = 50, y = 120)
        self.field8.place(x = 100, y = 120)
        self.field9.place(x = 150, y = 120)
        self.back.place  (x = 50, y = 180)
        self.reset.place (x = 150, y = 180)

    def singleplayer_window(self):
        self.sw = tkinter.Toplevel()
        self.sw.title("Singleplayer")

        # config
        self.sw.geometry("240x210")
        self.sw.resizable(width=0, height=0)
        self.sw.iconphoto(True, tkinter.PhotoImage(file=r'C:\Users\nicod\Desktop\TicTacToe\icon.png'))

        # draw the field
        self.field()

        self.sw.mainloop()

我希望你能帮帮我!

PS:我把多人功能放出来了,因为和单人功能差不多。

btw:这是我第一次真正的在课堂上工作,所以请不要怪我!

标签: pythontkinterattributes

解决方案


tkinter.Frame您永远不会使用super().__init__(self.root) Look at this进行初始化:

import tkinter as tkinter
from tkinter import *

# class for the game 
class Game(tkinter.Frame):
    def __init__(self):
        # main-window 
        self.root = tkinter.Tk()
        # title 
        self.root.title("TicTacToe")
        # text member
        self.text = tkinter.StringVar()
        self.text.set(" ")
        # config
        self.root.geometry("178x130")
        self.root.resizable(width=0, height=0)
        self.root['bg'] = '#1c6796'
        self.root.iconphoto(True, tkinter.PhotoImage(file=r'C:\Users\nicod\Desktop\TicTacToe\icon.png'))
        # buttons 
        self.singleplayer_button = Button(self.root, text = "Singleplayer", command = self.singleplayer_window, font = 'Times 10 italic')
        self.multiplayer_button = Button(self.root, text = "Multiplayer", command = self.multiplayer_window, font = 'Times 10 italic')
        self.quit_button = Button(self.root, text = "Quit", command = quit, font = 'Times 10 italic')
        self.singleplayer_button.place(x = 48, y = 10)
        self.multiplayer_button.place(x = 51, y = 50)
        self.quit_button.place(x = 70, y = 90)

        self.root.mainloop()

    def quit(self):
        self.root.destroy()

    def field(self):
        # 9 buttons for the field
        self.field1 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field2 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field3 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field4 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field5 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field6 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field7 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field8 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field9 = tkinter.Button(self, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.back   = tkinter.Button(self, text = 'back', command = quit, font = 'Times 10 italic')

        # display buttons
        self.field1.place(x = 50, y = 10)
        self.field2.place(x = 100, y = 10)
        self.field3.place(x = 150, y =10)
        self.field4.place(x = 50, y = 60)
        self.field5.place(x = 100, y = 60)
        self.field6.place(x = 150, y = 60)
        self.field7.place(x = 50, y = 120)
        self.field8.place(x = 100, y = 120)
        self.field9.place(x = 150, y = 120)
        self.back.place  (x = 50, y = 180)
        self.reset.place (x = 150, y = 180)

    def singleplayer_window(self):
        self.sw = tkinter.Toplevel()
        self.sw.title("Singleplayer")

        super().__init__(self.sw) # Initialise the frame
        super().pack() # `pack`/`grid`/`place` the frame

        # config
        self.sw.geometry("240x210")
        self.sw.resizable(width=0, height=0)
        self.sw.iconphoto(True, tkinter.PhotoImage(file=r'C:\Users\nicod\Desktop\TicTacToe\icon.png'))

        # draw the field
        self.field()

        self.sw.mainloop()

app = Game()

如果您singleplayer_window像@BryanOakley 所说的那样多次调用,那将导致问题。这就是为什么我认为你不应该继承的原因tkinter.Frame

import tkinter as tkinter
from tkinter import *

# class for the game 
class Game:
    def __init__(self):
        # main-window 
        self.root = tkinter.Tk()
        # title 
        self.root.title("TicTacToe")
        # text member
        self.text = tkinter.StringVar()
        self.text.set(" ")
        # config
        self.root.geometry("178x130")
        self.root.resizable(width=0, height=0)
        self.root['bg'] = '#1c6796'
        self.root.iconphoto(True, tkinter.PhotoImage(file=r'C:\Users\nicod\Desktop\TicTacToe\icon.png'))
        # buttons 
        self.singleplayer_button = Button(self.root, text = "Singleplayer", command = self.singleplayer_window, font = 'Times 10 italic')
        self.multiplayer_button = Button(self.root, text = "Multiplayer", command = self.multiplayer_window, font = 'Times 10 italic')
        self.quit_button = Button(self.root, text = "Quit", command = quit, font = 'Times 10 italic')
        self.singleplayer_button.place(x = 48, y = 10)
        self.multiplayer_button.place(x = 51, y = 50)
        self.quit_button.place(x = 70, y = 90)

        self.root.mainloop()

    def quit(self):
        self.root.destroy()

    def field(self):
        # 9 buttons for the field
        self.field1 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field2 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field3 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field4 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field5 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field6 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field7 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field8 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.field9 = tkinter.Button(self.frame, textvariable=self.text, command = self.move, height = 2, width = 4)
        self.back   = tkinter.Button(self.frame, text = 'back', command = quit, font = 'Times 10 italic')

        # display buttons
        self.field1.place(x = 50, y = 10)
        self.field2.place(x = 100, y = 10)
        self.field3.place(x = 150, y =10)
        self.field4.place(x = 50, y = 60)
        self.field5.place(x = 100, y = 60)
        self.field6.place(x = 150, y = 60)
        self.field7.place(x = 50, y = 120)
        self.field8.place(x = 100, y = 120)
        self.field9.place(x = 150, y = 120)
        self.back.place  (x = 50, y = 180)
        self.reset.place (x = 150, y = 180)

    def singleplayer_window(self):
        self.sw = tkinter.Toplevel()
        self.sw.title("Singleplayer")

        self.frame = tkinter.Frame(self.sw) # Initialise the frame
        self.frame.pack() # `pack`/`grid`/`place` the frame

        # config
        self.sw.geometry("240x210")
        self.sw.resizable(width=0, height=0)
        self.sw.iconphoto(True, tkinter.PhotoImage(file=r'C:\Users\nicod\Desktop\TicTacToe\icon.png'))

        # draw the field
        self.field()

        self.sw.mainloop()

app = Game()

推荐阅读