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

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

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

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

Tkinter

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

Q&A

解決済

2回答

12722閲覧

Tkinterでウィンドウの幅を取得したい

person

総合スコア223

Python 3.x

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

Tkinter

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

0グッド

1クリップ

投稿2020/01/07 11:03

編集2020/01/07 12:45

Tkinterでボタンをウィンドウ右上に表示したいです。ウィンドウサイズを変えたら、ボタンの位置もそれに応じて動くようにしたいです。

そのため、ウィンドウの幅を取得して使えばいいだろうと思って下のソースを書いたのですが、疑問点が2つあります。

1つは、最初のwinfo_width()の戻り値が最初は1になってしまい、ボタンをplaceで表示できないことです。

もう1つは、ボタンを動かすにはどうすればいいかわからないことです。このままでは同じ位置に固定してしまうのでbind("<Configure>")を考えたのですが、それだと何度も配置し直す感じで効率悪いような気もしますし、関数外で宣言したウィジェットを関数内で上手く破棄できないことです。

わかる方、回答よろしくお願いします。

Python

1import tkinter as tk 2 3win = tk.Tk() 4 5def test(): 6 print("x:",end="") 7 print(win.winfo_width()) 8 print("y:",end="") 9 print(win.winfo_height()) 10 11b = tk.Button(win, text="click", command=test) 12b.grid() 13#b.place(x=win.winfo_width()-50, y=0) 14 15#def test2(event): 16# win_x = win.winfo_width() 17# b.place(x=win_x-50, y=0) 18 19#win.bind("<Configure>", test2) 20 21#1が返ってくる・・・? 22print("x:",end="") 23print(win.winfo_width()) 24print("y:",end="") 25print(win.winfo_height()) 26 27win.mainloop()

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

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

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

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

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

guest

回答2

0

ウィジェット幅の取得値が1になってしまう件についてはupdate_idletasks()によって回避します.

import tkinter as tk win = tk.Tk() win.geometry("500x400+300+200") win.update_idletasks() print(win.winfo_width()) # ウィジェットの幅 print(win.winfo_height()) # ウィジェットの高さ print(win.winfo_x()) # ウィジェットの位置 x print(win.winfo_y()) # ウィジェットの位置 y win.mainloop()

投稿2020/06/20 01:59

P_Beginner

総合スコア99

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

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

0

ベストアンサー

サンプルを作ってみましたのでとりあえず確認ください。

Python

1import tkinter as tk 2 3win = tk.Tk() 4width=500 5height=500 6win.geometry(f"{width}x{height}") 7 8def callback(event): 9 global width, height 10 11 # Main Window以外のイベントは無視 12 if (event.type != 'configure') and (event.widget != win): 13 return 14 15 # サイズが変わってなかった無視 16 if (event.width == width) and (event.height == height): 17 return 18 19 # グローバル変数を更新 20 width = event.width 21 height = event.height 22 23 # ボタンを移動する 24 btn.place_forget() #不要かもしれないが、とりあえず明示的に記述しておく 25 btn.place(x=(width-200), y=0, width=200, height=30) 26 27# とりあえずは初期値を使って描画する 28btn = tk.Button(win, text="click me!") 29btn.place(x=(width-200), y=0, width=200, height=30) 30 31win.bind("<Configure>", callback) 32win.mainloop()

コードを見ていただくと解ると思うのですが、

1つは、最初のwinfo_width()の戻り値が最初は1になってしまい

Windowのサイズを指定して起動し、初期値としては指定したサイズを使用するとよいのではないでしょうか

このままでは同じ位置に固定してしまうのでbind("<Configure>")を考えたのですが、それだと何度も配置し直す感じで効率悪いような気もしますし

bind("<Configure>")を使う方法で良いのではないでしょうか。不要なイベントを排除する必要はありますが、今回の場合それほど複雑では無い気がします。

関数外で宣言したウィジェットを関数内で上手く破棄できないことです。

Widgetを生成・破棄するのではなく、再配置するだけで良いかと思います

投稿2020/01/08 00:29

編集2020/01/08 00:31
magichan

総合スコア15898

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

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

magichan

2020/01/08 00:37

あと書くのを忘れてましたが、何かレイアウトマネージャとしてplaceを使わなければならない理由があるのでしょうか? ボタンを右上に置きたいだけならば、packやgridを使うほうが数倍簡単かと思うのですが。
person

2020/01/08 05:01

回答ありがとうございます。 まだ学習中だったので、packの使い方を分かっていませんでした。 packを使うことにします。
magichan

2020/01/08 06:38

place 縛りがないのであれば、それが賢明でしょうね packであれば import tkinter as tk root = tk.Tk() bt = tk.Button(root, text='Click me!') bt.pack(anchor='ne') root.mainloop() だけでウィンドウサイズを変更しても常に右上に表示されるボタンが作成できます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問