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

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

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

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

Python

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

Q&A

解決済

1回答

1824閲覧

Python3のtkinterでヘッダー付きのScrolledFrameを作成したい

Yuiti628

総合スコア71

Tkinter

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

Python

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

0グッド

0クリップ

投稿2021/05/28 01:50

python3 でGUIを作成しております。

完成イメージ

イメージ説明
#現状
イメージ説明

問題点

ヘッダー部分をScrolledFrame何に入れると綺麗に配置されますが、スクロールバー の範囲内であるためスクロールすると見えなくなってしまいます。

ヘッダーフレームを用意し、下のウィジェットに合わしたいのですが、成功しません。
どうすれば良いのか教えて頂きたいです。

#現状のコード

python

1 2# tkinter 3import tkinter as tk 4from tkinter.ttk import * 5from ttkthemes import * 6from tkscrolledframe import ScrolledFrame 7 8 9class Application(Frame): 10 11 def __init__(self, master=None): 12 Frame.__init__(self,master) 13 master.resizable(0, 1) 14 15 # テーマ 16 style = Style() 17 style.theme_use('yaru') 18 self.pack(fill='both') #描写 19 20 #フォームの作成 21 self.CrateMainForm(master) 22 23 24 25 26 #region #メインフォームの作成 27 def CrateMainForm(self,master): 28 29 30 """ 31 ヘッダー 32 メールアドレス, パスワード, メッセージ 33 """ 34 35 Header = Frame(master) 36 Header.pack(padx=10 ,pady=5, fill="both") 37 38 # チェック 39 check = tk.BooleanVar(value = True) 40 checkBuntton = Checkbutton(Header, variable=check) 41 checkBuntton.grid(row=0, column=0, sticky="w") 42 43 # No ラベル 44 label = Label(Header) 45 label.configure(text="No.") 46 label.grid(row=0, column=1 ,pady=5) 47 48 # メールアドレス ラベル 49 label = Label(Header) 50 label.configure(text="メールアドレス") 51 label.grid(row=0, column=3,pady=5,padx=5) 52 53 54 # パスワード ラベル 55 label = Label(Header) 56 label.configure(text="パスワード") 57 label.grid(row=0, column=4) 58 59 60 # メッセージ ラベル 61 label = Label(Header) 62 label.configure(text="メッセージ", ) 63 label.grid(row=0, column=8 ,pady=5) 64 65 66 # スクロールバー フレーム 67 Sfram = ScrolledFrame(master , height =354) 68 Sfram._x_scrollbar.grid_forget() #水平方向のバーを削除 69 Sfram.bind_arrow_keys(root) 70 Sfram.pack(fill="both" ,expand = True) 71 # 中のフレーム 72 inner_frame = Sfram.display_widget(Frame) 73 74 # アカウント情報の表 75 self.Widget_items = [] 76 77 for i in range(50): 78 witems = self.CrateMainAccountForm(inner_frame, i) 79 self.Widget_items.append(witems) 80 81 # スクロールバー とTextの連動を防ぐため 82 for child in inner_frame.winfo_children(): 83 Sfram.bind_scroll_wheel(child) 84 Sfram.bind_scroll_wheel(inner_frame) 85 86 87 # サイズ調整 88 root.update() 89 Sfram.config(width=inner_frame.winfo_width()) 90 return 91 92 93 94 # アカウント情報の表 95 def CrateMainAccountForm(self, master, i): 96 97 items = [] 98 99 # 投稿チェック 100 check = tk.BooleanVar() 101 checkBuntton = Checkbutton(master, variable=check) 102 checkBuntton.grid(row=i +1, column=0, sticky="w") 103 items.append(checkBuntton) 104 105 106 # No ラベル 107 L_no1 = Label(master) 108 L_no1.configure(text=f"{i+1}",) 109 L_no1.grid(row=i +1, column=1) 110 111 112 # アイコンの表示 113 load_canvas = tk.Canvas(master , highlightthickness=0 , width=24 , height=24 , bg='#f5f6f7') 114 load_canvas.grid(row=i +1, column=2 , padx=2) 115 items.append(load_canvas) 116 117 118 # メールアドレス テキストボックス 119 TextMail = tk.StringVar() 120 MailBox = Entry(master, textvariable=TextMail ,width = 20 ) 121 MailBox.grid(row=i +1, column=3, sticky="nw") 122 items.append(MailBox) 123 124 125 # パスワード テキストボックス 126 TextPassword = tk.StringVar() 127 PasswordBox = Entry(master,textvariable=TextPassword ,width = 13,) 128 PasswordBox.grid(row=i +1, column=4, sticky="nw") 129 items.append(PasswordBox) 130 131 132 # メッセージ ラベル 133 label = Label(master, width = 25, anchor="w" ,text = '' ) 134 label.grid(row=i +1, column=8, padx =10) 135 label.grid_columnconfigure(0, weight = 1) 136 items.append(label) 137 138 return items 139 140 141#main 142if __name__ == "__main__": 143 144 root = ThemedTk() 145 app = Application(master=root) 146 app.mainloop() 147

解決方法の案

以前質問した時にこのようなコードを教えていただきました。

python

1# thead ... カラム名のフレーム 2# tbody ... 入力欄のフレーム 3# 双方のフレームに grid() で配置して、リサイズ時に入力欄の 4# grid_columnconfigure の minsize 値を反映します、 5 6def on_table_resize(event): 7 for idx in range(len(labels)): 8 size = thead.grid_columnconfigure(idx)["minsize"] 9 tbody.grid_columnconfigure(idx, minsize=size) 10 11tbody.bind("<Configure>", on_table_resize) 12

しかし、チェックボックス にminsizeがないようで成功しませんでした。
考えかたは理解できたのですが、実装に至っておりません。

下のウィジェットの位置とサイズを取得することなどはできないでしょうか?
place()で配置することでできないかなとも思ったのですが、無理でした。

何か他にも簡単な方法があったらお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

チェックボックス にminsizeがないようで成功しませんでした。

多分、ここの勘違いだと思います
grid_columnconfigure は、チェックボックスではなく、親となる「フレーム」のメソッドです。

thead -> Header と tbody -> inner_frame と読み替えて、試してみてください。

追記:

winfo_width() を参照する為、update() の後に

python

1 # サイズ調整 2 root.update() 3 4 for i, widget in zip([0,1,3,4,8], self.Widget_items[0]): 5 width = widget.winfo_width() 6 Header.grid_columnconfigure(i, minsize=width)

他の問題

BooleanVar や StringVar は、ローカル変数だと関数が抜けた時に破棄されるので、
インスタンス変数や items のリストに入れる等、参照を何処かに持たせる必要があります。
(誤動作の原因になります)

投稿2021/05/28 03:22

編集2021/05/28 04:29
teamikl

総合スコア8760

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

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

teamikl

2021/05/28 04:22 編集

スクロール内のフレームなので、リサイズイベントは発生しなさそうですね。 リサイズが発生しないなら、bind せずに、コードは直接呼び出しても良さそうです。 minsize は、配置済みのウィジェット等から算出して、 予め適当な値を設定しておく必要があります。 追記: padx,pady や sticky="nw" (左上寄せ) は、配置ズレの原因になります 追記2: column の index 値の違いにも注意、 column の配置が 0, 1, 3, 4, 8
Yuiti628

2021/05/29 03:34

解決しました!!!!! self.Widget_items これは、入力値だけ取得するために作っていたので問題が発生したいようです。 Checkbuttonはtk.BooleanVar()の方を入れていたいので、minsizeがなかったようです。 size調整用に一列分のラベルなども入れたものを作って、置き換えたら成功しました!!!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問