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

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

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

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

Python 3.x

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

Tkinter

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

Q&A

解決済

1回答

4065閲覧

Python3 Tk ウィジェットの配置について

IOError

総合スコア25

canvas

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

Python 3.x

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

Tkinter

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

0グッド

0クリップ

投稿2017/03/27 14:45

Python3 の Tk を使ってあるウィンドウを作りたいと思います。

○目標
・ウィンドウは左,右上,右下(順に win1, win2, win3 と呼ぶ)の3つの構成
・win1 は、番号の書いたリストボックスで上下に関してウィンドウのリサイズに対応
・win2 は、Canvasで縦の長さは固定、横幅はウィンドウのリサイズに対応
・win3 は、Canvasで上下左右ともにウィンドウのリサイズに対応

現時点で書いたコードを記載します。

python

1from tkinter import * 2 3def a(event): 4 canvas2.scan_mark(event.x, event.y) 5 6def b(event): 7 canvas2.scan_dragto(event.x, event.y, gain=1) 8 9if __name__ == '__main__': 10 w, h = 200, 200 # ウィンドウサイズ 11 r = 20 # 円の半径 12 13 root = Tk() 14 pw = PanedWindow(root, sashwidth = 10, orient = HORIZONTAL) 15 16 # ウィンドウ左側のリストボックス 17 listbox = Listbox(pw) 18 for i in range(50): 19 listbox.insert(END, i+1) 20 pw.add(listbox) 21 22 # ウィンドウ右側のスクロール可能Canvas 23 frame = Frame(root) 24 canvas = Canvas(frame, width = w, height = 30, bg = "#aaaaaa") 25 canvas2 = Canvas(frame, width = w, height = h, bg = "#cccccc", scrollregion=(0, 0, w*2, h*2)) 26 27 28 # キャンバス描画 29 oval = canvas2.create_oval(w-r, h-r, w+r, h+r) 30 31 canvas2.bind("<ButtonPress-1>",a) 32 canvas2.bind("<B1-Motion>",b) 33 34 35 # ウィジェットの配置 36 canvas.grid(row=0, column=0, sticky=E+W) 37 # スクロールバーの配置 38 xscroll = Scrollbar(frame, orient=HORIZONTAL, command=canvas2.xview) 39 xscroll.grid(row=3, column=0, sticky=E+W) 40 yscroll = Scrollbar(frame, orient=VERTICAL, command=canvas2.yview) 41 yscroll.grid(row=2, column=1, sticky=N+S) 42 43 canvas2.config(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set) 44 canvas2.grid(row=2, column=0, sticky=N+E+W+S) 45 46 frame.grid_rowconfigure(0, weight=1) 47 frame.grid_columnconfigure(0, weight=1) 48 frame.grid(sticky=N+E+W+S) 49 50 root.grid_rowconfigure(0, weight=1) 51 root.grid_columnconfigure(0, weight=1) 52 53 pw.add(frame) 54 pw.pack(expand = True, fill = BOTH) 55 56 root.mainloop()

上記のコードの問題点は、「ウィンドウのリサイズによって、win2 の位置が移動してしまい上下に余白ができてしまう」ことです。この部分を、「ウィンドウがリサイズされても win2 の位置は右上固定とし、win3 がリサイズされて余白ができない」というように改善したいと思います。

また、win2 右側が win3 のスクロールバーに合わせて、画面の右端まで届いていない状況です。これを win2 の幅と、win3 のスクロールバーまで含めた幅が一致するようにしたいです。
この点は追加ですので、可能であればアドバイスください。

わかる方がいらっしゃいましたらご教授ください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

求めてる挙動になってるかどうか怪しいですが、なんとなくできたので共有します。全文は長いのでgistにしました。

https://gist.github.com/tell-k/36d76665b866faf7c84c4993055ff0ec

ポイントは2点です。

61行目付近で rowconfigure を追加しました。そのとき一番上の行は weight=0 にしています。 weight=0 にすることでリサイズの影響を受けなくなり、上下に余白ができなくなります。

python

1 # rowconfigureで一行目を固定 2 frame.grid_rowconfigure(0, weight=0) 3 frame.grid_rowconfigure(1, weight=1)

10行目付近で、 ResizeCanvas(Canvas) を作って、それを canvas2 に設定しています。 ウィンドウのリサイズが発生するたびに、canvas2 の高さを自動的に調節してくれます。

class ResizeCanvas(Canvas): def __init__(self, *args,**kwargs): super().__init__(*args, **kwargs) self.frame = args[0] self.bind("<Configure>", self.on_resize) def on_resize(self,event): # 右下のCanvasをリサイズに合わせて高さを自動調整 self.height = self.frame.winfo_height() - 30 # 30 == canvas.height self.config(height=self.height)

参考

投稿2017/03/27 17:16

編集2017/03/27 17:17
tell_k

総合スコア2120

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

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

IOError

2017/03/28 04:09

tell_k さん、ありがとうございました。 まさにやりたかったことが実装されていました。 rowconfigure で欄を分けてしまえばよかったんですね。 また、ResizeCanvasクラスの init メソッドは初めて見る文法で、詳しい使い方がわからないので、これから勉強していこうと思います。 ご丁寧にリンクまで用意していただき、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問