ステーキの戯れ言

私のブログです。アドベントカレンダーを埋めるために作りました。

Python3とTkinter&canvasでマインスイーパーを作る

おはようございます。

長い事ブログ書いていないのは良くないということで、少し前にTkinterの練習用に作っていたプログラムをGitHubにあげてブログを書きました。
Python 3.7.0のwindows10です。

Tkinterとは?

超簡単にGUIが作れるお手軽ツール、Python2ではTkinter・ Python3ではtkinter

なぜTkinterを使っているのか?

色々あってPythonGUI使いたかったので、機能を一通り使ってみるということで作って見ました。

canvasって?

Tkinterウィジェット(画面構成をする部品)の一つであり、かなり自由に配置とかができる。

どこら辺が簡単なのか

詳しい使い方や関数はネットで調べましょう。
ただ本当に簡単で  

import tkinter

a = tkinter.Tk()
a.mainloop()

だけで

f:id:uragou:20190705153039p:plain
画面生成

画面ができる。

作ったマインスイーパ

GitHubをご覧ください。テストが終わったらここに貼ります。
Pythonバージョンが同じでも、環境によって見た目とか色々変わるため
どの環境でも動くと保証できないのが欠点(カラーコードとか大丈夫かな?)

github.com

起動するとこうなって…

f:id:uragou:20190705153922p:plain
ゲーム設定

こんな風に遊べる。

f:id:uragou:20190705153638p:plain
ゲーム画面

どんなことをしたか

1.画面の生成と削除・設定

上にも書いた通りtkinter.Tk()とmainloop()さえあれば画面はできる。
変数を複数用意すればその分画面ができる。

ちなみに一つをメイン画面にして、もう一つをサブ画面にするには

a = tkinter.Tk()
b = tkinter.Toplevel(master=a)

a.mainloop()

とすると、親画面が死ぬと子画面も死ぬようになる。

他には( a = tkinter.Tk() した後に)

ウィンドウのタイトル設定

a.title("マインスイーパー")

ウィンドウの初期サイズ

a.geometry("1200x720")
これは無くても画面内の部品によって大きさを調整してくれる。

ウィンドウの削除

a.destroy()

ちなみに画面にスクロールバーはつかない。
マインスイーパーには使わなかったのでここでは省略するが、本命の方ではかなり苦労した。
canvasモジュール内の部品で実現する。

画面を構成する部品を配置する。

import tkinter

def func():
    a_str.set( str( a_num.get() ) )

a = tkinter.Tk()

a_str = tkinter.StringVar()
tkinter.Label(master=a,textvariable= a_str).pack()

a_str.set("aaaa")
tkinter.Label(master=a,text= "bbbb").pack()

tkinter.Button(master=a,text="cccc",command=func).pack()

a_num = tkinter.Entry(master=a)
a_num.insert(tkinter.END,"dddd")
a_num.pack()

a_canvas = tkinter.Canvas(master=a,width = 100, height = 100)
a_canvas.pack()
a_canvas.create_rectangle(0,0,100,100,fill="red")

a.mainloop()

f:id:uragou:20190705162148p:plain
test2.py

画面だけがあってもしょうがない。
今回使った部品は

テキスト tkinter.Label

テキストはtext で内容を直接書くか、tkinter.StringVar()を入れた変数を,textvariable で指定することで配置できる。
setした内容は後からもう一度setすれば別の内容に書き換えられる。ちなみにStringVar以外にもIntVarとか色々ある。

ボタン tkinter.Button

text ボタンに文字などを書くことができ、command でボタンを押したときに実行される関数オブジェクトとかを指定できる。

入力欄 tkinter.Entry

Entryを作った後にinsertで初期入力値を指定、(第一引数は挿入される位置らしい。)
入力値は .get() でとることができる。

キャンバス tkinter.Canvas

高さと幅を指定すれば作成できる。
中には図形を書いたりスクロールバーを作れたりと色々便利

共通する事

複数画面を作ったりするときなどは、masterとしてどの画面の部品なのかをちゃんと指定してあげる事
変更とかが特にない部品については、変数を作る必要もない

pack()

各部品は作成した後に.pack()をすることで画面に配置される。
pack()はpackされた順に、下に新しく部品を追加していく。
色々とオプションをつければもう少し複雑な配置ができるが、画面に配置する機能は他にも

  • 表のように列と行を指定して部品を配置する.grid()
  • xとy座標を指定することで配置する.place()

がある。生成するだけなら引数とか特にいらない.pack()が便利

tkinter.Canvas

これが一番便利な部分。

  • ボタンに限らず様々な部品にイベントをつけることで様々な動作を実現
  • 大量のオブジェクトもタグを使って楽々管理
  • 一定時間ごとの処理をしながら入力イベントを受け付けられる。

マインスイーパーのテストが終わったら、プログラム貼り付けて記事を書く。