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

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

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

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Tkinter

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

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

Python

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

Q&A

解決済

1回答

2592閲覧

PYTHON3、TKINTERのスクロールバーが表示されない

temtemtemtem

総合スコア9

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Tkinter

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

スクロール

スクロールとは、ディスプレイスクリーン上において連続的にコンテンツが滑っていくことを指します。

Python

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

0グッド

0クリップ

投稿2020/05/25 02:27

編集2020/05/25 05:11

現在2つの同じフォーマットで作られたエクセルを比較するスクリプトを書いています。
その操作をGUI上で行いたいと思い、TKINTERを使用しています。
私の設計では大枠のWindowの中に6つのTabがあり、それぞれのタブで比較した結果が表示されるようにしたいです。
そして、大枠のWindowと各TAB内に作られるFrameにスクロールバーを設置しているつもりなのですが表示されません。
存在自体はありそうなのですが機能していない状況です。

スクロールバーについて別の質問なのですが、Treeview内でマウスのホイールでスクロールできるものとできないものがあります。
これは何が原因となっているのでしょうか。全てホイールでスクロールできるようにできるならそうしたいです。
よろしくお願いします。

python

1 2import tkinter as tk 3from tkinter import ttk 4import CostAnalysis 5import tkinter.scrolledtext as tksc 6 7 8def init_notebook(notebook): 9 10 for name, tab_name, class_name in zip(['Main', 'Upper', 'Sole', 'Sole Paint', 'Sundries', 'Packing'], 11 ['Main', 'Upper', 'Sole', 'Sole Paint', 'Sundries', 'Packing'], 12 [Main, Upper, Sole, SolePaint, Sundries, Packing]): 13 name = ttk.Frame(notebook) 14 notebook.add(name, text=tab_name) 15 class_name(master=name) 16 17 return notebook 18 19 20class ScrolledCanvas(tk.Canvas): 21 22 def __init__(self, master, *args, **kw): 23 super().__init__(master, *args, **kw) 24 25 bar_y = ttk.Scrollbar(self, orient=tk.VERTICAL) 26 bar_y.pack(side=tk.RIGHT, fill=tk.Y) 27 bar_y.config(command=self.yview) 28 29 bar_x = ttk.Scrollbar(self, orient=tk.HORIZONTAL) 30 bar_x.pack(side=tk.BOTTOM, fill=tk.X) 31 bar_x.config(command=self.yview) 32 33 self.config( 34 yscrollcommand=bar_y.set, 35 xscrollcommand=bar_x.set, 36 scrollregion=self.bbox("all"), 37 ) 38 39class MainWindow(ttk.Frame): 40 def __init__(self, master): 41 super().__init__(master) 42 43 canvas = ScrolledCanvas(self, width=2000, height=1000) 44 canvas.pack(fill=tk.BOTH, expand=True) # <- 配置は利用側で決める 45 46 notebook = init_notebook(ttk.Notebook(self)) 47 notebook.pack(fill=tk.BOTH, expand=True) 48 49 canvas.create_window((0, 0), 50 window=notebook, anchor=tk.NW, width=canvas.cget('width')) 51 52 self.canvas = canvas 53 self.notebook = notebook 54 55 56class Main(tk.Frame): 57 global result 58 result = CostAnalysis.data_scraping() 59 60 def __init__(self, master): 61 super().__init__(master) 62 self.pack(fill=tk.BOTH, expand=True) 63 self._MainCost_widget(result[0], 'File1 Basic information') 64 self._MainCost_widget(result[1], 'File2 Basic information') 65 self._MainCost_widget(result[2], 'File1 Cost information') 66 self._MainCost_widget(result[3], 'File2 Cost information') 67 self._MainCost_widget(result[4], 'Difference Cost information') 68 self._warning_frame(result[5]) 69 70 def _MainCost_widget(self, cost_info, txt): 71 frame_file = tk.LabelFrame(self, text=txt, width=1900, height=200, bg='#fff', fg='Blue') 72 frame_file.pack(pady=10, anchor=tk.NW) 73 74 for i in cost_info: 75 b = tk.LabelFrame(frame_file, text=i, bg='#fff') 76 c = tk.Label(b, text=cost_info[i], bg='#fff') 77 [widget.pack(side=tk.LEFT) for widget in (b, c)] 78 79 def _warning_frame(self, warning): 80 scrolledtext = tksc.ScrolledText(self, height=20, width=200, bg='black', fg='green') 81 scrolledtext.configure(highlightbackground='red') 82 scrolledtext.insert(tk.END, warning) 83 scrolledtext.pack() 84 85 86class Upper(tk.Frame): 87 def __init__(self, master): 88 super().__init__(master) 89 self.pack(fill=tk.BOTH, expand=True) 90 upper_result = result[6:10] 91 for i, name in enumerate(['Remove', 'Add', 'Changed point', 'Nothing Change']): 92 self._result_frame(name, upper_result[i]) 93 94 def _result_frame(self, name, upper_result): 95 remove = tk.Frame(self) 96 remove_label = tk.Label(remove, text=name) 97 remove_frame = tk.Frame(self, bg='#fff') 98 [widget.pack() for widget in (remove, remove_label)] 99 remove_frame.pack(fill=tk.BOTH, expand=True) 100 101 canvas = tk.Canvas(remove_frame, width=1900, height=300) 102 # Scrollbar を生成して配置 103 bar_y = tk.Scrollbar(canvas, orient=tk.VERTICAL) 104 bar_y.pack(side=tk.RIGHT, fill=tk.Y) 105 bar_y.config(command=canvas.yview) 106 107 bar_x = tk.Scrollbar(remove_frame, orient=tk.HORIZONTAL) 108 bar_x.pack(side=tk.BOTTOM, fill=tk.X) 109 bar_x.config(command=canvas.xview) 110 111 # Treeviewの作成 112 tree = ttk.Treeview(canvas) 113 tree["column"] = list(upper_result.columns) 114 tree["show"] = "headings" 115 # ヘッダーテキスト 116 117 for i in range(len(list(upper_result.columns))): 118 tree.heading(upper_result.columns[i], text=upper_result.columns[i]) 119 # 列の幅 120 tree.column(upper_result.columns[i], width=30) 121 for j in range(len(list(upper_result.index))): 122 # データ挿入 123 tree.insert("", "end", values=(list(upper_result.iloc[j]))) 124 125 # 設置 126 tree.pack(fill=tk.BOTH, expand=True) 127 # Canvas Widget を配置 128 canvas.config(yscrollcommand=bar_y.set, xscrollcommand=bar_x.set) 129 canvas.config(scrollregion=(0, 0, 4000, 5000)) # スクロール範囲 130 canvas.create_window((0, 0), window=tree, anchor=tk.NW, width=canvas.cget('width')) 131 canvas.pack(fill=tk.BOTH, expand=True) 132 133# 以下同じ様に各タブ用のFrameクラスを作成しました。省略します。 134 135def main(): 136 root = tk.Tk() 137 root.geometry("2000x1000") 138 root.title("テスト") 139 140 win = MainWindow(root) 141 win.pack(fill=tk.BOTH, expand=True) 142 143 root.mainloop() 144 145 146if __name__ == '__main__': 147 main() 148

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

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

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

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

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

teamikl

2020/05/25 05:07

ソースコードのレイアウトが崩れいて、 このままではコピーが困難なので修正をお願いします。 マークダウンでのソースコードの引用は 「クォート」''' ではなく「バッククォート」``` です
temtemtemtem

2020/05/25 05:13

修正しました。 このコード内ではファイルダイアログからエクセルファイルを選択する関数を使用していますが、別ファイルに格納してあるため呼び出せないことになっています。
teamikl

2020/05/25 05:18

実行ができません。result をなにか適当なデータに置き換えられますか? UIの問題の再現さえ出来ればいいので、内容は適当でいいのですが 出来ればコピーするだけで実行できる形での掲載をお願いします。
teamikl

2020/05/25 05:23 編集

init_notebook 内にも複数エラーが有るので、 実際に実行してるコードではないのでしょうか 訂正: ここは省略されてる箇所みたいですね。
teamikl

2020/05/25 05:30

実行できてませんが、コードで気になる点: キャンバスに create_windowで描画されてますが、何か意図があるのでしょうか? スクロールバーを持つウィジェット(canvas)が、フォーカスが得られておらず イベントが伝搬されてない可能性があります。 canvas にスクロールを付けるのではなく、Treeview に付けると解消するはずです。
guest

回答1

0

ベストアンサー

canvas.create_window 辺りが疑問点です。

例えば、Upper クラス内の構造では見た限り
スクロールバーを持っているのは canvas、フォーカスを得るのは Treeview
canvas のスクロールバーは Treeview と関連付けされていないため、
ホィールで Treeview 自体のスクロールは出来てもスクロールバーは連動しません。

解決策:
canvas.create_window を使わない。
スクロールバーは対象のウィジェットに直接つける。


動作確認用

python

1 2import tkinter as tk 3from tkinter import ttk 4 5 6class ScrolledMixin: 7 8 VERTICAL = "v" 9 HORIZONTAL = "h" 10 BOTH = VERTICAL+HORIZONTAL 11 12 def __init__(self, master, Container, orient, **kw): 13 frame = self 14 Container.__init__(frame, master, **kw) 15 16 if self.HORIZONTAL in orient: 17 hbar = ttk.Scrollbar(frame, orient=tk.HORIZONTAL) 18 hbar.pack(side=tk.BOTTOM, fill=tk.X) 19 hbar.config(command=frame.xview) 20 frame.config(xscrollcommand=hbar.set) 21 22 if self.VERTICAL in orient: 23 vbar = ttk.Scrollbar(frame, orient=tk.VERTICAL) 24 vbar.pack(side=tk.RIGHT, fill=tk.Y) 25 vbar.config(command=frame.yview) 26 frame.config(yscrollcommand=vbar.set) 27 28def _scrolled(class_, orient): 29 def __init__(self, master, **kw): 30 ScrolledMixin.__init__(self, master, class_, orient, **kw) 31 return type(class_.__name__, (class_, ScrolledMixin), locals()) 32 33# Scollbar decorator 34from functools import partial 35vscrolled = partial(_scrolled, orient=ScrolledMixin.VERTICAL) # 縦スクロール 36hscrolled = partial(_scrolled, orient=ScrolledMixin.HORIZONTAL) # 横スクロール 37scrolled = partial(_scrolled, orient=ScrolledMixin.BOTH) # 両方 38 39#### スクロールバーを付けたクラスの生成 40 41@scrolled 42class ScrolledCanvas(tk.Canvas): 43 pass 44 45@vscrolled 46class ScrolledTreeview(ttk.Treeview): 47 pass 48 49ScrolledText = scrolled(tk.Text) 50 51 52def init_notebook(notebook): 53 54 tab1 = ScrolledCanvas(notebook) 55 notebook.add(tab1, text="ScrolledCanvas") 56 57 tab2 = ScrolledTreeview(notebook, show="headings", column=[1]) 58 for num in range(100): 59 tab2.insert("", tk.END, values=[num]) 60 notebook.add(tab2, text="ScrolledTreeview") 61 62 tab3 = ScrolledText(notebook) 63 notebook.add(tab3, text="ScrolledText") 64 65 tab4 = ScrolledCanvas(notebook) 66 notebook.add(tab4, text="Treeview in ScrolledCanvas") 67 68 # Canvas に create_window で描画する場合、 69 # canvas のスクロールバーは Treeview に関連付けされていない 70 tree = ttk.Treeview(tab4, show="headings", column=[1]) 71 for num in range(100): 72 tree.insert("", tk.END, values=[num]) 73 tab4.create_window((10, 10), window=tree, anchor=tk.NW, height=400, width=400) 74 75 76 return notebook 77 78 79def main(): 80 root = tk.Tk() 81 root.geometry("800x800") 82 root.title("スクロールバーのテスト") 83 84 notebook = init_notebook(ttk.Notebook(root)) 85 notebook.pack(fill=tk.BOTH, expand=True) 86 87 root.mainloop() 88 89 90if __name__ == '__main__': 91 main() 92

投稿2020/05/25 05:57

teamikl

総合スコア8664

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

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

temtemtemtem

2020/05/25 16:47

いつも丁寧な回答ありがとうございます. この記述でtab4になっている方を実現したいのですが、Windowをリサイズすると(ドラッグ等で形を変えると)上に設置したTreeviewがスクロールバーの上に来てしまって見えなくなってしまいますよね。 それが私が改善したかった”スクロールバーが表示されない”だったということがteamiklさんのおかげで判明しました。この場合notebookとtab4の下にスクロールバーが隠れないような書き方はできるのでしょうか。何度も質問をしてしまい申し訳ありません。
teamikl

2020/05/25 19:04

スクロール対象がCanvas の時に scrollregion を設定するコードが抜けてました。 tab4.config(scrollregion=tab4.bbox("all")) で、リサイズした時にスクロールできるようになります。(tab1も同様)
teamikl

2020/05/25 22:29 編集

一つ不自然な点を見つけました。 親が異なってるようですが、canvas ではありませんか?(Upperクラス内) bar_y = tk.Scrollbar(canvas, orient=tk.VERTICAL) bar_x = tk.Scrollbar(remove_frame, orient=tk.HORIZONTAL) 両方ともcanvasへスクロールバーを付けてるのであれば、 ScrolledCanvas クラスを利用できるはずです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問