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

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

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

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

Python

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

Q&A

解決済

2回答

849閲覧

キャンバスに画像が表示されない

takatoyo

総合スコア13

Tkinter

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

Python

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

0グッド

0クリップ

投稿2021/11/16 07:31

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

Tkinterでアプリケーションを作りたいのですが、キャンバスに画像が表示されず困っています。

該当のソースコード

Python

1 2import numpy as np 3import cv2 4import PIL.Image,PIL.ImageTk 5import tkinter as tk 6from pickle import TRUE 7 8##### PATH設定 9MAHJONG_TILES_PATH = 'C:\university\guraduation research\pai_images\' # 麻雀牌画像パス 10PATH_DELIMITER = '\' 11 12### 定数定義 13Mahjong_tiles_types = ['ji1','ji2','ji3','ji4','ji5','ji6','ji7','man1','man2','man3','man4','man5','man6','man7','man8','man9', 14 'pin1','pin2','pin3','pin4','pin5','pin6','pin7','pin8','pin9','sou1','sou2','sou3','sou4','sou5','sou6','sou7','sou8','sou9'] 15tile_images = {} 16for tile in Mahjong_tiles_types: 17 tile_images[tile] = cv2.imread(MAHJONG_TILES_PATH + tile + '.png', cv2.IMREAD_COLOR) 18all_tiles = cv2.hconcat([tile_images['ji1'],tile_images['ji1'],tile_images['ji2'],tile_images['ji3'],tile_images['man1'],tile_images['man2'],tile_images['man3'], 19 tile_images['pin4'],tile_images['pin5'],tile_images['pin6'],tile_images['sou7'],tile_images['sou8'],tile_images['sou9']]) 20 21 22 23 24def title_btn1_click(): 25 global intro_frame0 26 main_frame.destroy() 27 intro_frame0 = tk.Frame(root) 28 root.title('ルールを知らない人向け(入門編)') 29 intro_frame0.pack() 30 intro_frame0.label = tk.Label(intro_frame0,font=('MSゴシック','20','bold'), text='このステップは麻雀のルールを全く知らない人向けです\nまずは麻雀の基本から学んでいきましょう') 31 intro_frame0.label.pack() 32 intro_tilebtn1 = tk.Button(intro_frame0, text="①麻雀牌の種類", height=10, width=80, command=intro_tilebtn1_click) 33 intro_tilebtn1.pack() 34 intro_agarikeibtn1 = tk.Button(intro_frame0, text="②4面子1雀頭のアガり形", height=8, width=80, command=intro_agarikeibtn1_click) 35 intro_agarikeibtn1.pack() 36 intro_yakubtn1 = tk.Button(intro_frame0, text="③役を覚える", height=8, width=80, command=intro_yakubtn_click) 37 intro_yakubtn1.pack() 38 39def title_btn2_click(): 40 global root_beginner 41 root.destroy() 42 root_beginner = tk.Tk() 43 root_beginner.geometry('1200x700') 44 root_beginner.title('ルールを覚えた人向け(初級者編)') 45 46def intro_tilebtn1_click(): 47 global intro_frame1 48 intro_frame0.label.destroy() 49 intro_frame0.destroy() 50 intro_frame1 = tk.Frame(root) 51 intro_frame1.label = tk.Label(root,font=('MSゴシック','20','bold'), text='まず麻雀に使用する道具に「牌(パイ、ハイ)」と呼ばれるものがあります\nこれは27種の数牌(すうはい、かずはい)と7種の字牌(じはい)から成り、\n1種類につき4個存在するので使用する総数は34種×4枚=136枚となります') 52 intro_frame1.label.place(x=80,y=100) 53 image = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(all_tiles)) 54 55 canvas = tk.Canvas(root,bg="green") 56 canvas.pack(expand = True,fill = tk.X) 57 canvas.create_image(10,10,image=image) 58 59 intro_tilebtn2 = tk.Button(root,text="次へ", width=8, command=intro_tilebtn2_click) 60 intro_tilebtn2.place(x=1100,y=300) 61 62def intro_tilebtn2_click(): 63 intro_frame1.label.destroy() 64 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="麻雀はこの136枚の牌から14枚の牌を手牌とし、\n特定の形に揃えてアガリを目指すゲームです") 65 intro_frame1.label.place(x=300,y=100) 66 intro_tilebtn3 = tk.Button(root,text="次へ", width=8, command=intro_tilebtn3_click) 67 intro_tilebtn3.place(x=1100,y=300) 68 69def intro_tilebtn3_click(): 70 intro_frame1.label.destroy() 71 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="数牌は漢数字で数字が描かれた萬子(マンズ)\n丸の数で数字を表す筒子(ピンズ)\n竹のようなマークの数で数字を表す索子(ソーズ)\nの3種類があります\nトランプのハートやダイヤのようなものです") 72 intro_frame1.label.place(x=250,y=50) 73 intro_tilebtn4 = tk.Button(root,text="次へ",width=8,command=intro_tilebtn4_click) 74 intro_tilebtn4.place(x=1100,y=300) 75 76def intro_tilebtn4_click(): 77 intro_frame1.label.destroy() 78 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="数牌は中国語の1~9と萬(マン)、筒(ピン)、索(ソー)を合わせて呼びます\n例えば萬子の5であれば5(ウー)と萬(マン)を合わせて五萬(ウーマン)と呼びます\n始めたばかりの時は呼び方はそれほど重要ではありません\n「漢数字の4」や「竹の6」など、自分の覚えやすい呼び方で大丈夫です") 79 intro_frame1.label.place(x=100,y=50) 80 intro_tilebtn5 = tk.Button(root,text="次へ",width=8,command=intro_tilebtn5_click) 81 intro_tilebtn5.place(x=1100,y=300) 82 83def intro_tilebtn5_click(): 84 intro_frame1.label.destroy() 85 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="字牌には東南西北の4つからなる風牌と白發中の3つからなる三元牌があります\n風牌は順番に東(トン)、南(ナン)、西(シャー)、北(ペイ)と読みます\n三元牌は順番に白(ハク)、發(ハツ)、中(チュン)と読みます") 86 intro_frame1.label.place(x=100,y=50) 87 intro_tilebtn6 = tk.Button(root,text="次へ",width=8,command=intro_tilebtn6_click) 88 intro_tilebtn6.place(x=1100,y=300) 89 90def intro_tilebtn6_click(): 91 intro_frame1.label.destroy() 92 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="日本とは違い、麻雀における方角の順番は東→南→西→北です\nまた三元牌の順番も白→發→中です\n後に登場する「ドラ」の理解に必要なので間違えないようにしましょう") 93 intro_frame1.label.place(x=150,y=50) 94 intro_tilebtn7 = tk.Button(root,text="次へ",width=8,command=intro_tilebtn7_click) 95 intro_tilebtn7.place(x=1100,y=300) 96 97def intro_tilebtn7_click(): 98 intro_frame1.label.destroy() 99 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="以上の34種の牌を使って麻雀はプレイされます\n次からは何をすればアガリになるのかを見ていきます") 100 intro_frame1.label.place(x=250,y=50) 101 102def intro_agarikeibtn1_click(): 103 global intro_frame1 104 intro_frame0.label.destroy() 105 intro_frame0.destroy() 106 intro_frame1 = tk.Frame(root) 107 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="麻雀では14枚の牌を手牌とし\n基本的には「4面子1雀頭」の形を完成させるとアガリとなります") 108 intro_frame1.label.place(x=220,y=50) 109 110 canvas = tk.Canvas(root,bg="green") 111 canvas.pack(expand = True,fill = tk.X) 112 image = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(all_tiles)) 113 canvas.create_image(10,10,image=image) 114 intro_agarikeibtn2 = tk.Button(root,text="次へ",width=8,command=intro_agarikeibtn2_click) 115 intro_agarikeibtn2.place(x=1100,y=300) 116 117def intro_agarikeibtn2_click(): 118 intro_frame1.label.destroy() 119 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="まずは面子(メンツ)の説明です\n面子とはある3つの牌の組み合わせをひとまとめにして1面子にします\nではその3つの牌の組み合わせとは何か?\nそれは「連続する3つの同じ色の数牌」(順子)または「3つの同じ牌」(刻子)です") 120 intro_frame1.label.place(x=100,y=50) 121 intro_agarikeibtn3 = tk.Button(root,text="次へ",width=8,command=intro_agarikeibtn3_click) 122 intro_agarikeibtn3.place(x=1100,y=300) 123 124def intro_agarikeibtn3_click(): 125 intro_frame1.label.destroy() 126 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="「連続する3つの同じ色の数牌」(順子)は123,678等といったものですが\n注意するべき点がいくつかあります\n①891、912等9から1はループして繋がりません\n②同じ色限定なので筒子と索子、萬子と筒子等は繋がりません\n③字牌は順子にはなりません、東南西、白發中は繋がりません") 127 intro_frame1.label.place(x=150,y=50) 128 intro_agarikeibtn4 = tk.Button(root,text="次へ",width=8,command=intro_agarikeibtn4_click) 129 intro_agarikeibtn4.place(x=1100,y=300) 130 131def intro_agarikeibtn4_click(): 132 intro_frame1.label.destroy() 133 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="「3つの同じ牌」(刻子)は文字通り同じ牌を3つ集めると面子となります\nこれはどの牌でも面子になるので数牌でも字牌でも3つ集めると面子になります") 134 intro_frame1.label.place(x=100,y=50) 135 intro_agarikeibtn5 = tk.Button(root,text="次へ",width=8,command=intro_agarikeibtn5_click) 136 intro_agarikeibtn5.place(x=1100,y=300) 137 138def intro_agarikeibtn5_click(): 139 intro_frame1.label.destroy() 140 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="次は雀頭の説明です\n雀頭の定義は「2つの同じ牌」(対子)です\n面子の条件の1つである「3つの同じ牌」より易しいですね") 141 intro_frame1.label.place(x=200,y=50) 142 intro_agarikeibtn6 = tk.Button(root,text="次へ",width=8,command=intro_agarikeibtn6_click) 143 intro_agarikeibtn6.place(x=1100,y=300) 144 145def intro_agarikeibtn6_click(): 146 intro_frame1.label.destroy() 147 intro_frame1.label = tk.Label(root,font=("MSゴシック","20","bold"),text="基本的には雀頭(対子)を1つと面子(順子か刻子)を4つ集めるとアガリとなります\n「国士無双」と「七対子」は例外的に4面子1雀頭の形ではありません\nこの2つについては次の「役」の説明で見ていきましょう") 148 intro_frame1.label.place(x=100,y=50) 149 150def intro_yakubtn_click(): 151 global intro_frame1 152 intro_frame0.destroy() 153 intro_frame1 = tk.Frame(root) 154 intro_frame1.label = tk.Label(intro_frame1,font=("MSゴシック","20","bold"),text="麻雀の役は40以上あります\nまずは基本的な役を覚えましょう") 155 intro_frame1.label.place(x=10,y=10) 156 one_han_yaku_btn = tk.Button(intro_frame1,text="1翻役", height=8, width=50, command=one_han_yaku_btn_click) 157 one_han_yaku_btn.place(x=1,y=10) 158 159def one_han_yaku_btn_click(): 160 intro_frame1.destroy() 161 162#ウィンドウの生成 163global root 164root = tk.Tk() 165root.title('麻雀初心者支援ツール') 166root.geometry('1200x700') #*ではなく小文字のxで記述 167main_frame = tk.Frame(root) 168main_frame.pack(fill = tk.BOTH, pady=20) 169global title_btn1 170title_btn1 = tk.Button(main_frame, width=80,height=10,font=('MSゴシック','15','bold'),text = 'ルールがわからない人向け',anchor=tk.CENTER,command=title_btn1_click) 171title_btn1.pack(fill = 'x', padx=100) 172global title_btn2 173title_btn2 = tk.Button(main_frame, width=80,height=10,font=('MSゴシック','15','bold'),text='ルールを覚えた人向け',anchor=tk.CENTER,command=title_btn2_click) 174title_btn2.pack(fill='x', padx=100) 175 176root.mainloop()

試したこと

ソースコードの順番を変えたりしましたが"ji2"にKeyErrorが出てしまいました。
上記のソースコードはエラーメッセージが表示されないので原因もわかりません。
どうぞよろしくお願い致します。

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

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

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

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

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

guest

回答2

0

ベストアンサー

コールバック関数の最後に root_beginner.update() を入れてみて下さい(intro_agarikeibtn1_click でも同様)。

python

1def intro_tilebtn1_click(): 2 global root_beginner 3 global intro_frame1 4 : 5 6 canvas.create_image(10,10,image=image) 7 8 intro_tilebtn2 = tk.Button(root,text="次へ", width=8, command=intro_tilebtn2_click) 9 intro_tilebtn2.place(x=1100,y=300) 10 root_beginner.update()

投稿2021/11/17 00:29

編集2021/11/17 01:19
melian

総合スコア20655

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

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

0

問題の原因: PhotoImage はデストラクタで解放されるようになってる為、
ローカル変数の場合、画像は関数を抜けた時に破棄されて
エラーは出ないが画像も表示されない状態になります。

解決策:
PhotoImage を持つ変数 image を、
グローバルやインスタンス変数等、他の場所に残る様にして見て下さい。

予め読み込んでおけるなら、tile_images の様に
グローバルの辞書にPhotoImage オブジェクトを入れておくとよいです。

投稿2021/11/16 16:30

teamikl

総合スコア8760

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

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

takatoyo

2021/11/16 20:26 編集

global image image=PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(all_tiles)) を all tiles = cv2.hconcat…(略 の下に入れて実行してみたのですが AttributeError: 'PhotoImage' object has no attribute'_PhotoImage__photo' というエラーメッセージが表示されてしまいました これは宣言の仕方に問題があるのでしょうか?
teamikl

2021/11/17 06:25 編集

PhotoImage 等のtkinter のオブジェクト生成は、 tkinter の初期化(root = tk.Tk())よりも後に行う必要があります。 ## 同じエラーを再現するコード。解決策は事前の初期化 # tk.Tk() の行のコメントを外してみてください。 import tkinter as tk from PIL import Image, ImageTk # root = tk.Tk() image = ImageTk.PhotoImage(Image.open("sample.png")) ---- 構造的な問題ですが、 途中でrootを破棄しているのも問題を起こしやすくする要因です。 tk.Tk() と mainloop の呼び出しは、プログラム中で一度のみとするようにしてください。 複数のウィンドウを利用したい場合は、tk.Toplevel を用いて iconify/withdrawメソッド で表示・非表示を切り替えるようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問