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

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

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

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

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

Q&A

解決済

1回答

1373閲覧

PyrhonのTkinterをつかってグラフを画面の真ん中に表示させたい

lteru

総合スコア6

Tkinter

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

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

0グッド

0クリップ

投稿2021/10/20 14:08

編集2021/10/21 02:41

前提・実現したいこと

PyrhonのTkinterをつかってグラフを画面の真ん中に表示させたい。

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

.grid()を使って"frame"の中心に"LabelFrame(border)"を表示させようと思っています。
ここで、tk.LabelFrameの親ウィジットに"frame"を指定するとなぜかLabelFrameが左上に配置され、anchorなどを指定しても位置が変わりませんでした。また、frameが消えてしまいました。

左上に表示される

import tkinter as tk # 1. メインウィンドウの作成 root = tk.Tk() root.title("Application") root.resizable(width=False,height=False) #ウィンドウ幅の固定 root.geometry("700x500") #=== オプション:フレームをつくる frame = tk.Frame(root, width=700, height=300, bg="#000080") frame.grid(column=0, row=0) #=== オプション:ラベルフレームウィジットをつくる border = tk.LabelFrame(frame, text="Form", fg='white', bg='#444', relief=tk.FLAT) border.grid(column=0, row=0) innerBox = tk.Frame(border, width=300, height=100) innerBox.grid() root.mainloop()

一方、親ウィジットをrootとするとframe内の真ん中に表示されました。

中央に表示される

import tkinter as tk # 1. メインウィンドウの作成 root = tk.Tk() root.title("Application") root.resizable(width=False,height=False) #ウィンドウ幅の固定 root.geometry("700x500") #=== オプション:フレームをつくる frame = tk.Frame(root, width=700, height=300, bg="#000080") frame.grid(column=0, row=0) #=== オプション:ラベルフレームウィジットをつくる border = tk.LabelFrame(root, text="Form", fg='white', bg='#444', relief=tk.FLAT) border.grid(column=0, row=0) innerBox = tk.Frame(border, width=300, height=100) innerBox.grid() root.mainloop()

frameの中央に配置したい場合、.gridの指定の仕方として、親ウィジットにframeを指定するのが正しい認識ですが、なぜこれだと真ん中に表示されず、rootだと画面の真ん中ではなくframeの真ん中に表示されるのでしょうか?

該当のソースコード

border = tk.LabelFrame(frame, text="Form", fg='white', bg='#444', relief=tk.FLAT)

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/10/20 17:34 編集

「左上に表示される」というほうのコード、`frame = tk.Frame(frame, ...` と `border = tk.LabelFrame(root, ...` の部分を質問に提示するコードとして書き間違えていないかご確認頂けますか。前者は `frame` の親に `frame` を設定しようとするのはおかしいですし、後者は後述の「該当のソースコード」で提示している問題点と合致しません。
lteru

2021/10/21 02:41

コードを簡素化した際に書き違えてました。ご指摘ありがとうございます。
guest

回答1

0

ベストアンサー

gridを中央に表示するには、grid()で配置する要素の親要素にgrid_anchor(tkinter.CENTER)を使います。

python

1import tkinter as tk 2 3root = tk.Tk() 4 5# gridを中央に寄せる 6root.grid_anchor(tk.CENTER) 7 8frame = tk.Frame(root) 9frame.grid() # 親要素rootのgrid(row=0, column=0)に配置

イメージとしては、親要素がgridという要素を持っていて、その中にframeborderを配置するイメージです。
そして、そのgrid自体の配置場所を中央にするメソッドがgrid_anchor()です。

grid()anchor引数は「gridセル内のどこに要素を配置するか」を決めるものなので、子要素が1つしか無くgrid自体を中央に持ってきたい今回の場合は指定しても見た目の変化がありません。

ご質問のコードでは一つの要素が一つの子要素を持つので、rootgrid_anchor(tkinter.CENTER)を設定すればあとは設定しなくてもよいでしょう。

なお、root.geometry('700 x 500')はエラーが出るので、修正しました。

python

1import tkinter as tk 2 3root = tk.Tk() 4root.title("Application") 5root.resizable(width=False,height=False) 6root.geometry('700x500') 7 8# gridを中央に配置 9root.grid_anchor(tk.CENTER) 10 11frame = tk.Frame(root, width=700, height=300, bg="red") 12frame.grid() 13 14border = tk.LabelFrame(frame, text="Form", fg='white', bg='#444', relief=tk.FLAT) 15border.grid() 16innerBox = tk.Frame(border, width=300, height=100) 17innerBox.grid() 18 19root.mainloop()

sample3

ではなぜ質問にあるような状態になったのでしょうか。
それぞれどうなっているのかを確認してみましょう。

まずご質問にある1つ目のコードです。

python

1import tkinter as tk 2 3# 1. メインウィンドウの作成 4root = tk.Tk() 5root.title("Application") 6root.resizable(width=False,height=False) 7root.geometry('700x500') 8 9frame = tk.Frame(root, width=700, height=300, bg="red") 10frame.grid() # これはrootのgrid(row=0, column=0)に配置される 11 12border = tk.LabelFrame(frame, text="Form", fg='white', bg='#444', relief=tk.FLAT) 13border.grid() # これはframeのgrid(row=0, column=0)に配置される 14innerBox = tk.Frame(border, width=300, height=100) 15innerBox.grid() # これはborderのgrid(row=0, column=0)に配置される 16 17root.mainloop()

このコードではrootframegridで配置し、frame内にbordergridで配置しています。
このときrootgridは上部に表示され、gridのサイズは子要素に合わせられます。
これはframegridも同様です。

すると、borderframegrid内の上部、framegridframe内の上部、frameroot内のgridの上部、そしてrootgridrootの上部、といった配置になり、それぞれのgridのサイズは子要素に合わせられますので、結果的にborderが左上に配置されたように見えます。

sample

一方、ご質問の2つ目のコードではframeborderrootgridで配置されています。
border.grid()と「どのセルに配置するか」を指定していませんので、frameの下のセルに追加されることに注意です。

python

1import tkinter as tk 2 3root = tk.Tk() 4root.title("Application") 5root.resizable(width=False,height=False) 6root.geometry('700x500') 7 8frame = tk.Frame(root, width=700, height=300, bg="#000080") 9frame.grid() # これはrootのgrid(row=0, column=0)に配置される 10 11border = tk.LabelFrame(root, text="Form", fg='white', bg='#444', relief=tk.FLAT) 12border.grid() # これはrootのgrid(row=1, column=0)に配置される 13innerBox = tk.Frame(border, width=300, height=100) 14innerBox.grid() # これはborderのgrid(row=0, column=0)に配置される 15 16root.mainloop()

rootgridrootの上部に表示され、その内部にframeborderが縦に配置されます。
このときgridのセルの大きさは一番大きいセルに合わせられますのでframeの大きさになります。
結果、borderの左右と下に隙間ができ、中央に表示されたように見えるのです。

sample2

回答のコードではrootgridを中央に配置しています。
その結果、borderframegridの上部、framegridframeの上部、framerootgridの上部、rootgridrootの中央部に表示され、それぞれgridのサイズは子要素のサイズに合わせられますのでborderが中央に表示されたように見えるのです。

以上、一部わかりにくかったかもしれませんが、お役に立てれば幸いです。

投稿2021/10/20 20:43

編集2021/10/20 20:49
fj68

総合スコア752

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

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

lteru

2021/10/21 04:14

わかりやすい説明ありがとうございます。 質問が言葉足らずでしたが、boderを配置したいのはrootではなくframeの中央でした。 また、frameの大きさは固定する想定でした。 ただ、教えていただいた frame.grid_anchor(tk.CENTER)とフレームを固定するframe.grid_propagate(0) でいけました! ありがとうございます。 ```Python import tkinter as tk root = tk.Tk() root.title("Application") root.resizable(width=False,height=False) root.geometry('700x500') frame = tk.Frame(root, width=700, height=300, bg="red") frame.grid() frame.grid_propagate(0) # フレーム幅の固定 frame.grid_anchor(tk.CENTER) border = tk.LabelFrame(frame, text="Form", fg='white', bg='#444', relief=tk.FLAT) border.grid(row = 0) innerBox = tk.Frame(border, width=300, height=100) innerBox.grid() root.mainloop() ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問