質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1684閲覧

Python tkinterでエラーが出てきます

mmmm66

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/10 03:08

プログラミング初心者です。
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/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

まず、関数とクラスとメソッドの勉強をすることをお勧めします。

公式ドキュメント Python チュートリアルをひととおり読みましょう。

特に公式ドキュメント Python チュートリアル 9. クラスを詳しく読みましょう。

その後で、コピペした元のソース達を読み見直して、どれが関数でどれがメソッドかを考えながら、最初からコードを作り直した方が良いと思います。

投稿2021/11/10 03:35

ppaul

総合スコア24666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

set_variables はメソッドではなく、グローバルの関数として定義されてます。

diff

1- win.set_variables() 2+ set_variables(win)

set_board 関数も同様の問題を抱えていますが、その後の
def set_button は引数 self を取るメソッドを想定されてるようなので、
関数定義全体で問題がありそうです。
各関数・メソッドのインデントが想定通りかどうかを見直してみてください。

オブジェクト win のメソッドとして呼び出したい場合は、
Toplevel を継承したクラス内で定義する必要があります。

投稿2021/11/10 03:26

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問