51871


**問題点**  
今tkinterのCanvasを使ってゲームを作っています。

しかし1つ問題があり、canvasではオブジェクト同士が重なると、新しく作成されたオブジェクトのほうが上の様に来るようになります。

例えば、ゲーム内の画面では、背景の上にキャラクターが来て、キャラクターの前に手前側オブジェクトが来る、といった仕組みになっているのでこれを作成しようと思えば・・・  
canvas=tk.Cancas.....  
ゲームの背景=canvas.create_image.....  
キャラクター=canvas.create_image.....  
手前側オブジェクト=canvas.create_image.....  
といった順番で作成されます。

しかし、ゲーム中で新しいキャラクターを登場させることになれば、それは手前側オブジェクトよりも新しく作成されることになるので、その新しいキャラクターとオブジェクトが重なったら、キャラクターが手前側に来てしまいます。

つまり、  
手前側オブジェクト=canvas.create_image.....  
の後で  
キャラクター2=canvas.create_image.....  
をすると、キャラクター2が手前側オブジェクトの前に来てしまう。

**考えてみた対策方法**  
そこでこの問題を解決するには、１つのCanvas上に画像を生成するのではなく、ゲーム背景専用、キャラークター専用そして手前側オブジェクト専用のCanvasを作成して、Canvasを重ね合わせて、それぞれのオブジェクト(ゲーム背景、キャラクター、オブジェクト)をそれぞれの対応するCanvas(ゲーム背景専用、キャラークター専用そして手前側オブジェクト専用)で作成すれば問題は解決できると思うんです。

Back_Ground_Layer=tk.Cancas.....  
Character_Layer=tk.Cancas.....  
Object_Layer=tk.Cancas.....

ゲームの背景=Back_Ground_Layer.create_image.....  
キャラクター=Character_Layer.create_image.....  
手前側オブジェクト=Object_Layer.create_image.....

つまり、１つのCanvasの上にすべての画像を作成しようとすると、新しいもの順に表示されてしまうけど  
それぞれのCanvasで新しい画像を生成しても、その上にはほかのCanvasがあるからしっかりと期待した順番に表示される という感じになると思うんです。

[![イメージ図](https://i.stack.imgur.com/J9Tp8.png)](https://i.stack.imgur.com/J9Tp8.png)

しかしそこで他の問題がありまして・・・  
実は、Canvasを作成するときには、Canvasの地色も設定しないといけないのですが、この地色が問題なのです。  
地色を透明に出来れば、下に来るCanvasのアイテムも見れるようになるのですが、透明になれなければ下のCanvasを覆いかぶさなってしまいます。

そこで、Canvasの地色を透明にする方法を探しているのですが・・・どうすればいいでしょうか？  
また、他の解決方法などはありますでしょうか？


CC BY-SA 4.0
2019-01-10T11:45:19.200
51869
2020-06-04T09:10:17.877
2019-01-10T12:10:15.210
31713
31713
question
python python3 tkinter
地色が透明なCanvasを作成したい。


**近そうなものを見つけたので先頭に追記**  
Canvasのバックグラウンドカラーを 0 (無効な色?) に設定するらしいです。  
[How to make a tkinter canvas background
transparent?](https://stackoverflow.com/q/53021603/9014308)

> The only possible config(... option, to set the background to nothing
>
> `c.config(bg='')`
>
> results with: _tkinter.TclError: unknown color name ""
>
> you have to hold the chess board and figures within the same `.Canvas(....`
[code]

    self.canvas = Canvas(self, width=500, height=200, bd=0, highlightthickness=0)
    self.canvas.create_rectangle(245,50,345,150, fill='white')
    
    self.image = tk.PhotoImage(file='chess.png')
    self.image_id = self.canvas.create_image(50,50, image=self.image)
    
    self.canvas.move(self.image_id, 245, 100)
    
[/code]

* * *

表示(描画が開始される時間的な)順番ではなくZオーダー(手前か奥か)の制御ならば、  
`lift` と `lower` で制御出来るのでは？  
[Stacking Order Maintenance in
Tkinter](https://stackoverflow.com/q/9576063/9014308)  
[python tkinter grid_forget -
Tkinterでは、ウィジェットを見えないようにする方法はありますか？](https://code.i-harness.com/ja-
jp/q/3a475a)

> 1つのオプションは、別の答えで説明されているように、 pack_forgetまたはgrid_forgetを使用すること 。 もう1つの選択肢は、
> liftとlowerを使用することです。 ウィジェットの積み重ね順序が変更されます。
> 正味の効果は、兄弟ウィジェット（または兄弟の子孫）の後ろにウィジェットを隠すことができることです。
> あなたが目に見えるようにするには、あなたはそれらをlift 、目に見えないようにしたいときはlowerします

* * *

表示順番対策としてモノになるかは不明ですし、Canvasではありませんが、  
ウインドウの透明バックグラウンドの記事があります。応用できるかもしれません。

ただし「クロスプラットフォームな方法は無い」と回答が付いています。  
macOS と Windows のそれぞれ用の方法が提示されています。  
[Transparent background in a Tkinter
window](https://stackoverflow.com/q/19080499/9014308)

> Here is a solution for macOS:
[code]

    import tkinter as tk
    
    root = tk.Tk()
    # Hide the root window drag bar and close button
    root.overrideredirect(True)
    # Make the root window always on top
    root.wm_attributes("-topmost", True)
    # Turn off the window shadow
    root.wm_attributes("-transparent", True)
    # Set the root window background color to a transparent color
    root.config(bg='systemTransparent')
    
    root.geometry("+300+300")
    
    # Store the PhotoImage to prevent early garbage collection
    root.image = tk.PhotoImage(file="photoshop-icon.gif")
    # Display the image on a label
    label = tk.Label(root, image=root.image)
    # Set the label background color to a transparent color
    label.config(bg='systemTransparent')
    label.pack()
    
    root.mainloop()
    
[/code]

> It is possible, but it's OS-dependent. This will work in Windows:
[code]

    import Tkinter as tk # Python 2
    import tkinter as tk # Python 3
    root = tk.Tk()
    # The image must be stored to Tk or it will be garbage collected.
    root.image = tk.PhotoImage(file='startup.gif')
    label = tk.Label(root, image=root.image, bg='white')
    root.overrideredirect(True)
    root.geometry("+250+250")
    root.lift()
    root.wm_attributes("-topmost", True)
    root.wm_attributes("-disabled", True)
    root.wm_attributes("-transparentcolor", "white")
    label.pack()
    label.mainloop()
    
[/code]

他に後から追記されてそうな簡単な回答がありましたが、上記を含めて動作確認はしていません。

> You can do this: `window.attributes("-transparentcolor", "somecolor")`

他にゲームでは使え無さそうですが、こんな記事があります。  
[Python tkinter
で多角形(図形)を半透明に重ねる方法を教えてください。](https://teratail.com/questions/126353)  
[Tkinterを使って透明ウィジェットを作成するには？](https://stackoverrun.com/ja/q/4636845)  
[python - tkinter winfo_ -
どのようにTkinterで形状のアルファを変えることができますか？](https://code.i-harness.com/ja-jp/q/ec0727)


CC BY-SA 4.0
2019-01-10T12:16:46.717
51871
2019-01-10T13:00:01.240
2020-06-17T08:14:45.997
-1
26370
51869
answer


Canvasのオブジェクトの表示順序を変えるのならば以下のメソッドで可能だと思いますよ。  
[tag_raise()](https://effbot.org/tkinterbook/canvas.htm#Tkinter.Canvas.tag_raise-
method)  
[tag_lower()](https://effbot.org/tkinterbook/canvas.htm#Tkinter.Canvas.tag_lower-
method)


CC BY-SA 4.0
2020-06-04T09:10:17.877
67281
2020-06-04T09:10:17.877
40477
51869
answer