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

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

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

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

Tkinter

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

Python

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

Q&A

解決済

1回答

3953閲覧

tkinterのpackが正常に動かない

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

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

Tkinter

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

Python

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

0グッド

0クリップ

投稿2019/04/24 10:14

実現したいこと

「ほげ」と書いてあるボタンが右寄せで出てきて、それを押したら
「ぴよ」と書いてあるボタンが右寄せで「ほげ」の下に出てくる

発生している問題

「ぴよ」が「anchor=Tk.W」を無視して中央に出てくるのですが、どうすれば正常に動きますか。ちなみにanchor以外の引数も無視されますしgridやplaceを使ってもだめでした。エラーメッセージは出ていません。

該当のソースコード

Python

1import tkinter as Tk 2 3class App(Tk.Frame): 4 5 def __init__(self, master=None): 6 Tk.Frame.__init__(self, master) 7 Tk.Button(text='ほげ', command=self.btn_event).pack(anchor=Tk.W) 8 9 def btn_event(self): 10 Tk.Button(self, text='ぴよ').pack(anchor=Tk.W) 11 12if __name__ == '__main__': 13 14 mm = App() 15 mm.pack() 16 mm.mainloop()

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

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

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

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

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

guest

回答1

0

ベストアンサー

どうすれば正常に動きますか。

最初にちょっと脱線ですが「正常に動かない」と言いたくなる気持ち自分にもわかります。「なぜ自分が指定したとおりに配置しないんだtkinterよ...」と言いたくなりますね。しかし自分はGUIアプリ作成を通じて「GUIシステムはあくまで自分の指示通りに動いているだけで、原因のほぼ100%が自分の仕様把握不足や注意不足に起因する」ということを学びました。ここは冷静に「どういう具合にレイアウトされているか」を確認するのがよいと思います。

まず書いた通りに正常に動いていることを示します。

それを示すためにレイアウトが行われている様子をデバッグプリントしてみました。

python

1import tkinter as tk 2 3 4class App(tk.Frame): 5 def __init__(self, master=None): 6 tk.Frame.__init__(self, master) 7 dbg_conf(self) 8 b1 = tk.Button(text='ほげ', command=self.btn_event) 9 dbg_conf(b1) 10 b1.pack(anchor=tk.W) 11 12 def btn_event(self): 13 b2 = tk.Button(self, text='ぴよ') 14 dbg_conf(b2) 15 b2.pack(anchor=tk.W) 16 17 18def dbg_conf(w): 19 w.bind('<Configure>', on_conf) 20 21 22def on_conf(ev): 23 print(f"widget={ev.widget} width={ev.width} height={ev.height} x={ev.x} y={ev.y}") 24 25 26if __name__ == '__main__': 27 mm = App() 28 mm.pack() 29 mm.mainloop()

(自分はtkinterの別名をTkじゃなくてtkとする習慣なので回答のコードではそう変えさせていただきました。)

===>

# 初期レイアウト動作 widget=.!button width=31 height=26 x=0 y=0 <--(B1) widget=.!app width=1 height=1 x=59 y=26 <--(A1) # ボタンを押したときに起きるレイアウト動作 widget=.!app.!button width=1 height=1 x=0 y=0 <--(B2) widget=.!app width=30 height=26 x=45 y=26 <--(A2) widget=.!app.!button width=30 height=26 x=0 y=0 <--(B2)

(B1), (B2)のxに着目してください。いずれも親に対してx座標が0、すなわち最西端に配置されてます。これはanchor=tk.Wの仕様通りです。

期待通りでない原因(+α)

  • (1) b2のの配置

b2はAppフレームの子供となっています。Appフレームのpackには何も指定してないのでデフォルト動作として親(所謂rootウィンドウ)に対して水平方向中央に配置されます。またAppフレームの大きさはb2を配置するのに必要最小限の大きさになります。つまりb2自体はAppフレームの最西端に配置されるのですが、Appフレームの方がrootに対して中央に配置されているので結局b2はウィンドウの左端には配置されなくなります。

  • (2) b1の配置

こちらは原因とはちょっと違いますが・・・
b1はroot直下に配置されてます。Appフレームのpackはb1より後なのでrootに対してb1, Appフレームの順に並びます。まずこの階層自体が意図通りではないと思います。本当は
tk.Button(text='ほげ', command=self.btn_event)
ではなく
tk.Button(self, text='ほげ', command=self.btn_event)
のつもりだったのではないでしょうか?

対処案

対処方法は一通りではありませんが、一例をあげると

(1) Appフレームはpack(fill=tk.BOTH)で配置する
こうすればAppフレームがボタンの大きさではなくrootウィンドウの大きさに合わせて広がってくれます。

(2) b1もAppフレームの子供にする
(1)だけでも見た目は期待どおりになりますが気持ち悪いので・・・


Windows 10, CPython 3.7, Tcl/Tk 8.6

投稿2019/04/24 12:01

編集2019/04/24 12:04
KSwordOfHaste

総合スコア18394

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

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

退会済みユーザー

退会済みユーザー

2019/04/24 12:47

色々教えていただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問