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

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

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

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

Tkinter

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

Python

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

Q&A

解決済

2回答

2508閲覧

Tkinterでのcommandとしてのメソッド呼び出し時「selfが入力されていない」と表示される

Qiitahana

総合スコア4

Python 3.x

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

Tkinter

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

Python

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

0グッド

0クリップ

投稿2021/12/14 09:26

前提・実現したいこと

予め登録してある画像をTkinterを使用しランダムに表示する
くじ引き(ガチャ)アプリを作ろうとしています。

発生している問題・エラーメッセージ

現在、1回(くじ引きを)やるのButton ウィジェットを押すと
ゲームを管理しているクラスのくじ引き処理用関数をコマンドとして呼び出す
部分を作ろうとしているのですが、
command = クラス名.関数名 としてボタンを押して処理のメソッドを
呼び出した際、メソッド定義の際に書く[self]が一般的な引数と認識されるのか
[self]が決められていませんとなります。

#IDLEのShellに表示されるエラー gacha() missing 1 required positional argument: 'self'

該当のソースコード

import tkinter as tk from tkinter import messagebox from tkinter import filedialog import random class Tkinter: def __init__(self, master): self._master = master self._question = tk.Label(text = "くじ引きをしてみよう。", font = ("Arial", 30), wraplength = 1000, bg = "#FFFAB1") self._question.pack(pady = 60) #Frame for 2 buttons self._frame1 = tk.Frame(bg = "#FFFAB1") self._frame1.pack(pady = 10) self._1 = tk.Button(self._frame1, text = "1回やる", font = ("Arial", 30), width = 8, height = 2, bg = "#90D031", command = Game.gacha) self._1.pack(side = tk.LEFT, padx = 15) self._10 = tk.Button(self._frame1, text = "10回やる", font = ("Arial", 30), width = 8, height = 2, bg = "#DF1B3F", command = Game.gacha10) self._10.pack(side = tk.LEFT, padx = 15) #Charadex self._dex = tk.Button(text = "持っている画像", font = ("Arial", 30), width = 14, height = 2, bg = "#276AA6") self._dex.pack(side = tk.BOTTOM, expand = tk.TRUE) #Menubar to quit menubar = tk.Menu(master) master.config(menu = menubar) bar = tk.Menu(menubar) menubar.add_cascade(label = "メニュー", menu = bar) bar.add_command(label = "辞める", command = Game.quitgacha) def cm(self): cm = messagebox.showinfo("感謝状","遊んでくれてありがとう!") class Game: def __init__(self, master): self._master = master self._dom = None def gachacontrol(self): gift = random.randint(1, 100) if gift <= 17: self._dom = "///.JPG" elif gift <= 35: self._dom = "///.jpg" elif gift <= 50: self._dom = "///.JPG" elif gift <= 65: self._dom = "///.JPG" elif gift <= 80: self._dom = "///.JPG" elif gift <= 95: self._dom = "///.JPG" elif gift == 96: self._dom = "///.png" elif gift == 97: self._dom = "///.png" elif gift == 98: self._dom = "///.JPG" else: self._dom = "///.JPG" def gacha(self): #Randomly choose 1 num from 1 to 100 to decide the gift to come out result = tk.Tk() result.title("結果") self.gachacontrol() result.mainloop() def gacha10(self): #gacha * 10 count = 1 result = tk.Tk() result.title("結果") while count != 10: self.gachacontrol() count += 1 result.mainloop() def quitgacha(self): ans = messagebox.askokcancel("ゲーム終了", "本当に辞めますか。") if ans: Tkinter.cm() root.destroy() root = tk.Tk() root.title("Gachanter") root.configure(bg = "#FFFAB1") view = Tkinter(root) controller = Game(root) root.mainloop()

試したこと

クラス.の部分を直接クラス名にしたり、selfにしたり複数通り
思いつくことを試しましたが解決しませんでした。

補足情報(FW/ツールのバージョンなど)

開発環境: IDLE(Python 3.9 64-bit)

selfが一般引数と認識されエラーが出る問題は全てのコマンド呼び出しで発生していますが、
ごちゃごちゃすることを避けるためその一例を取り上げさせていただきました。

なお、コードは
・辞めるためのメニュー
・どの画像が選ばれるか決める関数
・一通りのUI
の部分のみ完成している状態です。

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

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

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

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

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

guest

回答2

0

自己解決

クラス名.メソッド名()としていたのが問題だと分かりました。
引数の役割関係なくインスタンス化として認識されていたのだと思われます。

クラスをインスタンス化したものを入れた変数(controller)に.メソッド名をつけ、
controller = Game(root)でのGameのインスタンス化をview = Tkinter(root) (commandを持つ「1回やる」のボタンがあるクラス) より先に行ったところ、
正常に作動しました。
(変更点: 19、22、33行目 > 変数.メソッド名()への変更 100、101行目 > GameクラスをTkinterクラスより先にインスタンス化。)

ご協力くださった方本当にありがとうございました。

python

1import tkinter as tk 2from tkinter import messagebox 3from tkinter import filedialog 4import random 5 6 7 8class Tkinter: 9 10 def __init__(self, master): 11 self._master = master 12 self._question = tk.Label(text = "くじ引きをしてみよう。", 13 font = ("Arial", 30), wraplength = 1000, bg = "#FFFAB1") 14 self._question.pack(pady = 60) 15 #Frame for 2 buttons 16 self._frame1 = tk.Frame(bg = "#FFFAB1") 17 self._frame1.pack(pady = 10) 18 self._1 = tk.Button(self._frame1, text = "1回やる", font = ("Arial", 30), width = 8, height = 2, 19 bg = "#90D031", command = controller.gacha) 20 self._1.pack(side = tk.LEFT, padx = 15) 21 self._10 = tk.Button(self._frame1, text = "10回やる", font = ("Arial", 30), width = 8, height = 2, 22 bg = "#DF1B3F", command = controller.gacha10) 23 self._10.pack(side = tk.LEFT, padx = 15) 24 #Charadex 25 self._dex = tk.Button(text = "持っている画像", font = ("Arial", 30), width = 14, height = 2, 26 bg = "#276AA6") 27 self._dex.pack(side = tk.BOTTOM, expand = tk.TRUE) 28 #Menubar to quit 29 menubar = tk.Menu(master) 30 master.config(menu = menubar) 31 bar = tk.Menu(menubar) 32 menubar.add_cascade(label = "メニュー", menu = bar) 33 bar.add_command(label = "辞める", command = controller.quitgacha) 34 35 def cm(self): 36 cm = messagebox.showinfo("感謝状","遊んでくれてありがとう!") 37 38 39class Game: 40 41 def __init__(self, master): 42 self._master = master 43 self._dom = None 44 45 def gachacontrol(self): 46 gift = random.randint(1, 100) 47 if gift <= 17: 48 self._dom = "IMG_0313.JPG" 49 elif gift <= 35: 50 self._dom = "IMG_0110_Moment.jpg" 51 elif gift <= 50: 52 self._dom = "IMG_0405.JPG" 53 elif gift <= 65: 54 self._dom = "IMG_0151.JPG" 55 elif gift <= 80: 56 self._dom = "IMG_6331 (2).JPG" 57 elif gift <= 95: 58 self._dom = "IMG_E0827.JPG" 59 elif gift == 96: 60 self._dom = "qiita cat.png" 61 elif gift == 97: 62 self._dom = "rare qiita cat.png" 63 elif gift == 98: 64 self._dom = "IMG_0873.JPG" 65 else: 66 self._dom = "IMG_0149.JPG" 67 68 69 def gacha(self): 70 #Randomly choose 1 num from 1 to 100 to decide the gift to come out 71 result = tk.Tk() 72 result.title("結果") 73 self.gachacontrol() 74 result.mainloop() 75 76 77 def gacha10(self): 78 #gacha * 10 79 count = 1 80 result = tk.Tk() 81 result.title("結果") 82 while count != 10: 83 self.gachacontrol() 84 count += 1 85 result.mainloop() 86 87 def quitgacha(self): 88 ans = messagebox.askokcancel("ゲーム終了", "本当に辞めますか。") 89 if ans: 90 Tkinter.cm() 91 root.destroy() 92 93 94 95 96 97root = tk.Tk() 98root.title("Gachanter") 99root.configure(bg = "#FFFAB1") 100controller = Game(root) 101view = Tkinter(root) 102root.mainloop()

投稿2021/12/14 11:11

Qiitahana

総合スコア4

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

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

melian

2021/12/14 11:27

Game.quitgacha() の Tkinter.cm() 部分でエラーが発生するのではないでしょうか(修正前と同じ理由で)。
Qiitahana

2021/12/14 11:50

quitgachaの部分気付いていませんでした。 ご指摘の通り修正したところ正常に作動しました。 ありがとうございます。
guest

0

python

1 Tkinter.cm()

は、

python

1 self.cm()

でないといけないですね。

投稿2021/12/14 09:32

ppaul

総合スコア24670

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

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

Qiitahana

2021/12/14 10:57

ご解答ありがとうございます。 cmメソッドは、cmメソッドを呼び出しているquitgachaメソッドが属するクラス(Game)と別(Tkinter)にあるため、selfだと機能しないと思います。 試しに二つクラスを作り、片方でもう片方のメソッドを呼び出すコードを書いてみました。 self.メソッド名()とすると「そのようなメソッドは存在しない」となりますが、クラス名.メソッド名()とどのクラスのメソッド化明記すると正常に作動します。 ///////////// class App:     def __init__(self, master):         self._master = master     def test(self):         print("Correct") class Pass:     def __init__(self, master):         self._master = master     def passing(self):         app.test() master = 1 app = App(master) pa_ss = Pass(master) pa_ss.passing() /////////// また、元々のコードでは、各メソッドの呼び出し時なぜかself引数が一般の引数の様に認識されてしまい メソッド呼び出しごとに「<メソッド名> missing 1 required positional argument: "self"」のエラーが出てしまいそもそもメソッド自体が実行されてくれません。
Qiitahana

2021/12/14 11:49

他の型のご指摘で気付いたのですが、正しくはcmメソッドをインスタンス化に使った変数で呼び出す(view.cm())が正解でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問