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

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

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

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

Tkinter

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

Q&A

解決済

1回答

6302閲覧

Tkinterでcanvas内のFrameでのスクロールバーを一番下へ行く方法を教えてください

tatsu0117

総合スコア11

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2020/03/08 13:23

###canvas内のFrameでスクロールバーが自動で一番下に行くようにしたいです
いつもお世話になっております。
手探りでプログラムを勉強しているためご質問させていただいている内容が文章的に至らない点があるかと思いますが、
ご容赦頂ければ幸いです。

Tkinterを使用して、表形式の入力ソフトを開発しております。
以前、Entryの最終行でエンターを押すと新しい行が追加されるような動作をさせるところまではお力添えのおかげで
できるようになりました。

しかし、行を追加することによって下のほうへと見えない位置まで追加されてしまうことが判明いたしました。
そこで、スクロールバーを設けてスクロールすることで追加された行まで行けるようにしたいと思い現在のプログラムの形になりました。
canvasを使って、スクロールバーを表示させてマウスの左クリックで下まで行くことはできるようになったのですが、
行が追加され、最終行がスクロールバーの出る位置まで来たときに自動で一番下の行を表示するようにできず困っております。
該当するコードは下記になります。
どこまで表示すれば伝わりやすいのかがまだわからないため、長くなってしまいますがすべてのプログラムを掲載させていただきます。
###該当のソースコード

Python

1from tkinter import * 2from tkinter import ttk 3import tkinter as tk 4from tkinter import filedialog 5import pandas as pd 6 7class AutoScrollbar(Scrollbar): 8 # A scrollbar that hides itself if it's not needed. 9 # Only works if you use the grid geometry manager! 10 def set(self, lo, hi): 11 if float(lo) <= 0.0 and float(hi) >= 1.0: 12 # grid_remove is currently missing from Tkinter! 13 self.tk.call("grid", "remove", self) 14 else: 15 self.grid() 16 Scrollbar.set(self, lo, hi) 17 def pack(self, **kw): 18 raise TclError("cannot use pack with this widget") 19 def place(self, **kw): 20 raise TclError("cannot use place with this widget") 21 22 23# create scrolled canvas 24 25root = Tk() 26 27vscrollbar = AutoScrollbar(root) 28vscrollbar.grid(row=0, column=1, sticky=N+S) 29hscrollbar = AutoScrollbar(root, orient=HORIZONTAL) 30hscrollbar.grid(row=1, column=0, sticky=E+W) 31 32canvas = Canvas(root, yscrollcommand=vscrollbar.set, xscrollcommand=hscrollbar.set) 33canvas.grid(row=0, column=0, sticky=N+S+E+W) 34 35vscrollbar.config(command=canvas.yview) 36hscrollbar.config(command=canvas.xview) 37 38# make the canvas expandable 39root.grid_rowconfigure(0, weight=1) 40root.grid_columnconfigure(0, weight=1) 41 42# create canvas contents 43frame = ttk.Frame(canvas) 44frame.rowconfigure(1, weight=1) 45frame.columnconfigure(1, weight=1) 46 47n = 5 48 49#入力用フレーム 50def addText(event): 51 row_size = len(list_Items1) 52 activerow = event.widget.grid_info()['row'] 53 54 if row_size == activerow: 55 #項目1追加 56 label0 = ttk.Label(frame,text=activerow+1) 57 label0.grid(row=activerow+1, column=0) 58 list_Items1.append(tk.StringVar()) 59 entry_Item1 = ttk.Entry(frame, 60 textvariable=list_Items1[activerow], 61 width=10) 62 entry_Item1.grid(row=activerow+1,column=1) 63 entry_Item1.bind("<Return>", addText) #全てのEntryにbind 64 entry_Item1.focus_set() 65 frame.update_idletasks() 66 canvas.config(scrollregion=canvas.bbox("all")) 67 else: 68 # row : activerow+1 , column : 1 のWidgetを検索 69 for w in frame.winfo_children(): 70 if (w.grid_info().get('row') == activerow+1) and (w.grid_info().get('column') == 1): 71 w.focus_set() 72 break 73#項目をつくる 74list_Labels = ['a', 'b', 'c','d','e','f','g','h','i','j'] 75for i in range(0, len(list_Labels)): 76 label0 = ttk.Label(frame, 77 text=list_Labels[i]) 78 label0.grid(row=0, column=i,sticky = 'w') 79 if i == 9: 80 frame.grid_columnconfigure(i, weight = 1) 81#項目1 82for i in range(0, n): 83 label0 = ttk.Label(frame,text=i+1,width=5,anchor='c',background="#ff0000") 84 label0.grid(row=i+1, column=0,sticky = 'w') 85#項目2 86global list_Items1 87list_Items1 = [0] * n 88for i in range(0, n): 89 list_Items1[i] = tk.StringVar() 90 entry_Item1 = ttk.Entry(frame, 91 textvariable=list_Items1[i], 92 width=15) 93 entry_Item1.grid(row=i+1,column=1) 94 entry_Item1.bind("<Return>", addText) #全てのEntryにbind 95for w in frame.winfo_children(): 96 if (w.grid_info().get('row') == 1) and (w.grid_info().get('column') == 1): 97 w.focus_set() 98 break 99#項目3 100global list_Items2 101list_Items2 = [0] * n 102for i in range(0, n): 103 list_Items2[i] = tk.StringVar() 104 entry_Item2 = ttk.Entry(frame, 105 textvariable=list_Items2[i], 106 width=30) 107 entry_Item2.grid(row=i+1,column=2) 108 entry_Item2.bind("<Return>", addText) #全てのEntryにbind 109#項目4 110list_Items3 = [0] * n 111for i in range(0, n): 112 list_Items3[i] = tk.StringVar() 113 entry_Item3 = ttk.Entry(frame, 114 textvariable=list_Items3[i], 115 width=30) 116 entry_Item3.grid(row=i+1,column=3) 117#項目5 118for i in range(0, n): 119 label1 = ttk.Label(frame, 120 text=i+1,width=10,anchor='c') 121 label1.grid(row=i+1, column=4) 122#項目6 123for i in range(0, n): 124 label2 = ttk.Label(frame, 125 text=i+1,width=10,anchor='c') 126 label2.grid(row=i+1, column=5) 127#項目7 128for i in range(0, n): 129 label3 = ttk.Label(frame, 130 text=i+1,width=10,anchor='c') 131 label3.grid(row=i+1, column=6) 132#項目8 133for i in range(0, n): 134 label4 = ttk.Label(frame, 135 text=i+1,width=10,anchor='c') 136 label4.grid(row=i+1, column=7) 137#項目9 138global list_Condition 139list_Condition = [0] * n 140for i in range(0, n): 141 list_Condition[i] = ttk.Combobox(frame, 142 state='readonly', 143 width=10) 144 list_Condition[i]['values'] = ('aa', 'bb', 'cc', 'dd') 145 list_Condition[i].grid(row=i+1, column=8) 146 list_Condition[i].current(1) 147#項目10 148global list_Comment 149list_Comment = [0] * n 150for i in range(0, n): 151 list_Comment[i] = tk.StringVar() 152 entry_Comment = ttk.Entry(frame, 153 textvariable=list_Comment[i]) 154 entry_Comment.grid(row=i+1,column=9,sticky = 'nsew') 155 frame.grid_columnconfigure(9, weight = 1) 156 entry_Comment.bind("<Return>", addText) #全てのEntryにbind 157#項目11 158global list_delivery 159list_delivery = [0] * n 160for i in range(0, n): 161 list_delivery[i] = ttk.Combobox(frame, 162 state='readonly', 163 width=15) 164 list_delivery[i]['values'] = ('aaa', 'bbb', 'ccc', 'ddd') 165 list_delivery[i].grid(row=i+1, column=10) 166 list_delivery[i].current(0) 167 168canvas.create_window(0, 0, anchor=NW, window=frame) 169frame.update_idletasks() 170canvas.config(scrollregion=canvas.bbox("all")) 171 172def ButtonClicked_Run(): 173 print("a") 174button_Run = ttk.Button(root, 175 text='情報取得', 176 padding=10, 177 command=ButtonClicked_Run) 178button_Run.grid(row=2, column=0,sticky = 'nsew',pady=20) 179root.grid_columnconfigure(0, weight = 1) 180 181root.mainloop()

###試したこと
def addText(event):内のcanvas.config(scrollregion=canvas.bbox("all"))の次の行にsee("end")を追加してみましたが、
対応しておらず、一番下の行の表示ができませんでした。
また、項目10のEntryをFrameのサイズが変わるごとにリサイズしたいのですが、
そちらもcanvasを追加した途端にうまくいかなくなってしまいました。
もし可能でしたら、そちらの方法も併せてご教示いただけますと幸いです。
ルール違反でしたら大変申し訳ございません。
お手数をおかけいたしますが、どうぞよろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

addText()関数内の

Python

1 canvas.config(scrollregion=canvas.bbox("all"))

の行の下にて

Python

1 canvas.yview_moveto(canvas.bbox("all")[3])

を追加みてください

投稿2020/03/09 07:17

magichan

総合スコア15898

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

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

tatsu0117

2020/03/09 08:37

magichan様 いつもご回答ありがとうございます! やりたかったことができました。 ここでもう一つ質問するのはダメなのかもですが、canvasは自動でリサイズされるのですが frameが自動でリサイズされずに困っております。 何かいい方法などありませんでしょうか? ご教示いただけますと幸いです。 よろしくお願いいたします。
tatsu0117

2020/03/09 09:27

やはり新しく質問を追加させていただきます!
magichan

2020/03/09 09:31

スミマセン。 ちょっといま時間が取れないので。。 あとで動作確認いたします。
tatsu0117

2020/03/09 14:22

お忙しいところすみません。。。 ここ数日ずっと自分で考えているのですがどうしてもわからず・・・ お手数をおかけいたしますがよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問