プログラミング初心者です。
Python tkinterでOXゲームを作っています。
メインウィンドウのボタンを押すと別のウィンドウが出て、その別ウィンドウでゲームを行いたいのですが、
AttributeError: 'Toplevel' object has no attribute 'set_variables'
というエラーが出てしまいます。
該当のソースコード
import threading import time import random import tkinter as tk class Thread(threading.Thread): def __init__(self): super(Thread, self).__init__() self.is_running = True self.thlock = 1 self.keylock = 0 self.parent = None self.start() def __call__(self): self.keylock = 1 self.unlock() def set_parent(self, parent): self.parent = parent def lock(self): self.thlock = 1 def unlock(self): self.thlock = 0 def is_lock(self): return self.thlock def random_choice(self): time.sleep(0.5) i = random.choice([i for i, v in enumerate(self.parent.board2info) if v == 0]) tag = self.parent.alpstr[i] self.parent.update_board(i, tag) if self.parent.result: self.lock() return self.parent.playerTurn = 1 self.lock() self.keylock = 0 def alpha_zero(self): pass def run(self): while self.is_running: if self.is_lock(): continue self.random_choice() table = """ Turn {} |{:^3s}|{:^3s}|{:^3s}| ------------- |{:^3s}|{:^3s}|{:^3s}| ------------- |{:^3s}|{:^3s}|{:^3s}| """ table_r = """ 結果: {} |{:^3s}|{:^3s}|{:^3s}| ------------- |{:^3s}|{:^3s}|{:^3s}| ------------- |{:^3s}|{:^3s}|{:^3s}| """ def check(board): wins = [[0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]] for i in range(len(wins)): if board[wins[i][0]]==board[wins[i][1]]==board[wins[i][2]]==1: return 1 elif board[wins[i][0]]==board[wins[i][1]]==board[wins[i][2]]==-1: return 1 return [2, 0][0 in board] def sub_window(): win = tk.Toplevel() win.geometry("{}x{}+{}+{}".format(360, 400, 450, 100)) win.title("三目並べ") cv= tk.Canvas(win,background="gold", width=640, height=480) cv.place(x=0, y=0) win.set_variables() win.set_board() win.set_button() win.thread = Thread() win.thread.set_parent(self) def set_variables(win): win.result = 0 win.playerTurn = 1 win.board2info = [0] * 9 win.symbol = " ox" win.alpstr = "abcdefghi" win.winner = ["", "あなた", "引き分け", "CPU"] def set_board(win): win.board = tk.Canvas(self, bg="white", width=340, height=340) win.tag2pos = {} position = [(20, 20, 120, 120), (120, 20, 220, 120), (220, 20, 320, 120), (20, 120, 120, 220), (120, 120, 220, 220), (220, 120, 320, 220), (20, 220, 120, 320), (120, 220, 220, 320), (220, 220, 320, 320)] for tag, pos in zip(self.alpstr, position): win.tag2pos[tag] = pos[:2] win.board.create_rectangle(*pos, fill='green yellow', outline='green yellow', tags=tag) win.board.tag_bind(tag, "<ButtonPress-1>", self.pressed) # Vertical line for x in range(120, 320, 100): win.board.create_line(x, 20, x, 320) # Horizontal line for y in range(120, 320, 100): win.board.create_line(20, y, 320, y) win.board.place(x=10, y=0) def set_button(self): win.reset = tk.Button(self, text="reset", relief="groove", command=self.clear) win.reset.place(x=170, y=360) win.quit_program = tk.Button(self, text="quit", relief="groove", command=self.close) win.quit_program.place(x=320, y=360) def clear(self): win.board.delete("all") win.set_variables() win.set_board() win.thread.keylock = 0 def draw_symbol(self, tag): symbol = win.symbol[win.playerTurn] x, y = win.tag2pos[tag] win.board.create_text(x+50, y+50, font=("Helvetica", 60), text=symbol) def pressed(self, event): if win.thread.keylock: return item_id = win.board.find_closest(event.x, event.y) tag = self.board.gettags(item_id[0])[0] #print("Tag {} pressed...".format(tag)) action = win.alpstr.index(tag) state = win.board2info[action] if state in [-1, 1]: return win.update_board(action, tag) if win.result: win.thread.keylock = 1 return win.thread() def update_board(self, action, tag): win.board2info[action] = win.playerTurn win.draw_symbol(tag) win.check_result() win.playerTurn = -win.playerTurn def check_result(self): result = check(win.board2info) winner = "Turn {}".format("?") if result: winner = win.winner[result] if result == 2 else self.winner[self.playerTurn] print(table_r.format(winner, *[[" ", "o", "x"][i] for i in self.board2info])) else: print(table.format("?", *[[" ", "o", "x"][i] for i in self.board2info])) win.result = result def close(self): win.thread.is_running = 0 win.quit() def run(self): win.mainloop() #-------------------------------------------------------------------------- root = tk.Tk() root.geometry("600x600") root.title("シュミレーションゲーム") canvas0= tk.Canvas(background="#cea", width=600, height=600) canvas0.place(x=0, y=0) label0= tk.Label(canvas0, text="ゲーム施策") label0.place(x=300,y=450,anchor=tk.CENTER) button = tk.Button(canvas0, text="サブウィンドウ生成", command=sub_window) button.place(x=300,y=500) root.mainloop()
試したこと
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。