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

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

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

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

Tkinter

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

Q&A

解決済

1回答

1659閲覧

frame,tkinterでのコントロール配置及び設定が不明です

shin0859

総合スコア15

Python 3.x

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

Tkinter

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

1グッド

0クリップ

投稿2021/05/25 23:42

前提・実現したいこと

pythonの初心者です。
tkinterでメニュー画面を作っています。
アップimageよりblueのフレームが画面高になりません
又コントロール配置がpack、gridで制御出来ていません
ご指導願います。
それと、その先ですが画面にcontrol-frameとcanvas-frameを
設けていますが、buttonのon/offでcontrol-frameの左右スライド
(視覚的スライドにコントロールフレームwidthtを縮めてゼロに、同時にcontrol-frameを広げる)
を考えていますが可能でしょうか併せてご指導ください。

下記のページから引用してます
https://daeudaeu.com/play_movie/
アップコードは関連場所のみとしています。

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

イメージ説明

該当のソースコード

python

1import tkinter as tk 2from tkinter import ttk 3import tkinter.messagebox as msgbox 4from PIL import Image, ImageTk 5 6class Model(): 7 def __init__(self): 8 # 読み込んだフレーム 9 self.frames = None 10 11class View(): 12 def __init__(self, app, model): 13 self.master = app 14 self.model = model 15 # アプリ内のウィジェットを作成 16 self.create_widgets() 17 18 # クリックされたら実行 19 def btn_click(self): 20 msgbox.showinfo("クリックイベント", "が入力されました。") 21 22 def create_widgets(self): 23 # キャンバスのサイズ 24 canvas_width = 800 25 canvas_height = 480 26 27 # メインフレームの作成と配置 28 self.main_frame = tk.Frame(self.master,bg="yellow") 29 self.main_frame.pack() 30 31 # コマンドフレームの作成と配置 32 self.operation_frame = tk.Frame(self.main_frame,bg="blue") 33 self.operation_frame.grid_propagate(1) 34 self.operation_frame.grid(column=0, row=1) 35 36 # 映像フレームの作成と配置 37 self.canvas_frame = tk.Frame(self.main_frame) 38 self.canvas_frame.grid(column=1, row=1) 39 40 # 映像キャンバスの仕様 41 self.canvas = tk.Canvas( 42 self.canvas_frame, 43 width=canvas_width, 44 height=canvas_height, 45 bg="black") 46 self.canvas.pack() 47 48 # info_Label 49 la = ttk.Label(self.operation_frame, 50 text="メニュー選択", 51 width=10, 52 font=("Meiryo UI", 12, "bold")) 53 la.pack(padx=10, pady=10, side=tk.TOP) 54 #la.grid( column=0, row=0, padx=50, pady=10, ipadx=0) 55 #la.place(relx=0.05, rely=0.05) # 横0.05、縦0.1の位置に配置 56 57 # selectFile_Combobox 58 List = ['all select', 'folder1', 'folder2', 'folder3'] 59 str = tk.StringVar() 60 cmb = ttk.Combobox( 61 self.operation_frame, 62 values=List, 63 width=10, 64 font=("Meiryo UI", 12), 65 textvariable=str, 66 state='readonly') 67 cmb.set(List[0]) 68 cmb.bind('<<ComboboxSelected>>',lambda e: print('str=%s' % str.get())) 69 #cmb.bind('<<ComboboxSelected>>', selectFile_changed) 70 #cmb.grid(row=1, column=0, padx=5, pady=5) 71 #cmb.pack(padx=20, pady=10, anchor=tk.W) 72 cmb.pack(padx=20, pady=10, side=tk.TOP) 73 74 # Order_Radiobutton 75 rb1 = tk.Radiobutton( 76 self.operation_frame, 77 value=0, 78 text="shuffle", 79 width=10, 80 bg="Lightblue", 81 font=("Meiryo UI", "12")) 82 rb1.select() 83 #rb1.grid(column=0, row=2, padx=0, pady= 10, ipadx=0) 84 #rb1.place(relx=0.05, rely=0.35) 85 #rb1.pack(padx=20, anchor = tk.NW) 86 rb1.pack(padx=20, pady=10, side=tk.TOP) 87 88 # Order_Radiobutton 89 rb2 = tk.Radiobutton( 90 self.operation_frame, 91 value=1, 92 bg="Lightblue", 93 font=("Meiryo UI", "12"), 94 text="normal", 95 width=10) 96 rb2.deselect() 97 #rb2.grid(column=0, row=3, padx=0, pady= 10, ipadx=0) 98 #rb2.place(relx=0.05, rely=0.50) 99 #rb2.pack(padx=20, anchor = tk.W) 100 rb2.pack(padx=20, pady=10, side=tk.TOP) 101 102 # load_button 103 image1 = Image.open('./inifile/start.png') 104 image1 = image1.resize(size=(46, 43)) 105 self.img1 = ImageTk.PhotoImage(image1) 106 self.btn1 = tk.Button( 107 self.operation_frame, 108 image=self.img1, 109 relief="flat", 110 command = self.btn_click) 111 #self.btn1.grid(column=0, row=4, padx=0, pady= 10, ipadx=0) 112 #self.btn1.place(relx=0.05, rely=0.65) 113 #self.btn1.pack(padx=20, pady=10, anchor=tk.W) 114 self.btn1.pack(padx=20, pady=10, side=tk.TOP) 115 116 # exit_button 117 image2 = Image.open('./inifile/exit.png') 118 image2 = image2.resize(size=(46, 43)) 119 self.img2 = ImageTk.PhotoImage(image2) 120 self.btn2 = tk.Button( 121 self.operation_frame, 122 image=self.img2, 123 relief="flat", 124 command = self.btn_click) 125 #self.btn2.grid(column=0, row=5, padx=10, pady= 10, ipadx=10) 126 #self.btn2.place(relx=0.05, rely=1.80) 127 self.btn2.pack(padx=20, pady=10, side=tk.TOP) 128 129if __name__ == "__main__": 130 app = tk.Tk() 131 app.title("Digital Photo Slide view") 132 model = Model() 133 view = View(app, model) 134 # controller = Controller(app, model, view) 135 app.mainloop()

試したこと

補足情報(FW/ツールのバージョンなど)

--環境--
python3.8
tkinter8.6
pycharm2021.1

teamikl👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

pack() の伸縮オプションは、.pack(fill=tk.BOTH, expand=tk.YES)

grid() の伸縮オプションは、

  • 親ウィジェットの .grid_rowconfigure(), .grid_columnconfigure()
  • grid() のオプションで、.grid(row=0, column=0, sticky=tk.NSEW)

 NSEW: 全方向、NS: 縦、EW: 横

grid の configure で伸縮可能な領域と、
sticky で、実際に伸縮する際の方向を指定します。


blueのフレームが画面高になりません

diff

1- self.operation_frame.grid(column=0, row=1) 2+ self.operation_frame.grid(column=0, row=1, sticky=tk.NS)

コントロール配置がpack、gridで制御出来ていません

ここは完成形がどのようなイメージなのか解らないので、
制御できていないというのは、具体的にどの部分を指してるのでしょうか?

control-frameの左右スライド

(視覚的スライドにコントロールフレームwidthtを縮めてゼロに、同時にcontrol-frameを広げる)
を考えていますが可能でしょうか

やりたいことは可能ですが、実装方法は検討が必要で、
「pack()/grid() を使う場合の width 」は、自動的に計算される値な為、直接指定しても効果はありません。

  • grid() では、width の代わりに、grid_columnconfigure の minsize で変更できます。
  • grid_forget() で、レイアウトを解除し、非表示にすることが可能です。

 再計算が必要なので、親クラスの grid_propagate(0)

  • lift(), lower() で、レイヤーの様に他のウィジェットで覆いかぶせる方法もあります。
  • 任意の width を直接指定したい場合は、place() で配置することになります。

メニューフレーム表示非表示のサンプル

python

1 2from types import SimpleNamespace 3import tkinter as tk 4 5 6def create_view(root): 7 menu_frame = tk.Frame(root, width=200, bg="blue") 8 main_frame = tk.Frame(root, width=400, bg="black") 9 10 exit_button = tk.Button(menu_frame, text="Exit") 11 exit_button.pack() 12 hide_button = tk.Button(menu_frame, text="Hide") 13 hide_button.pack() 14 show_button = tk.Button(main_frame, text="Show") 15 # show_button.pack() 16 17 menu_frame.grid(row=0, column=0, sticky=tk.NSEW) 18 main_frame.grid(row=0, column=1, sticky=tk.NSEW) 19 20 root.grid_propagate(tk.NO) 21 root.grid_rowconfigure(0, weight=1) 22 root.grid_columnconfigure(0, minsize=200) 23 root.grid_columnconfigure(1, weight=1) 24 25 return SimpleNamespace(**locals()) 26 27 28def main(): 29 root = tk.Tk() 30 root.geometry("600x600") 31 view = create_view(root) 32 33 def show_animation(maxsize=200): 34 def animation(value): 35 value = min(value, maxsize) 36 root.grid_columnconfigure(0, minsize=value) 37 if value < maxsize: 38 root.after(20, animation, value+20) 39 40 view.show_button.pack_forget() 41 view.menu_frame.grid(row=0, column=0, sticky=tk.NSEW) 42 43 root.after_idle(animation, 10) 44 45 def hide_animation(value=200): 46 def animation(value): 47 value = max(0, value-20) 48 root.grid_columnconfigure(0, minsize=value) 49 if value > 0: 50 root.after(20, animation, value) 51 else: 52 view.root.grid_propagate(False) 53 view.menu_frame.grid_forget() 54 view.show_button.pack() 55 root.after_idle(animation, value) 56 57 def toggle_menu(e): 58 is_shown = root.grid_columnconfigure(0)["minsize"] 59 if is_shown: 60 hide_animation() 61 else: 62 show_animation() 63 64 root.bind_all("<F4>", toggle_menu) 65 view.exit_button.config(command=root.quit) 66 view.hide_button.config(command=hide_animation) 67 view.show_button.config(command=show_animation) 68 69 root.mainloop() 70 71 72if __name__ == '__main__': 73 main()

投稿2021/05/26 10:09

teamikl

総合スコア8760

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

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

shin0859

2021/05/26 10:31

teamikl様 早々のコメント有難うございます。 self.operation_frame.grid(column=0, row=1, sticky=tk.NS) だけでも 凄くうれしく思います。 メニューフレーム表示非表示のサンプル のコードは内容が重すぎて、 しばらく理解に時間が掛かりそうです。 まずは、コントロールの配置を考えて行きたいと思います。 大変貴重なコード提示及びアドバイスに感謝いたします。 もうしばらく、開けておきます。
shin0859

2021/05/26 11:02

その後ですが メニューフレーム表示非表示のサンプル のコードは自分の希望そのものでした。凄い! 中身のコード理解は、う~ムですが、理解に努力したいと思います。 あと思ったのですが、pythonにはコントロールアニメーションに特化したプラグインは 無いのでしょうか? ネット上に見当たらなかったので...  例えばjQueryやハンバーガーメニュー等 全部自前のコードで処理するのでしょうか どなたかご存知でしたら、お知らせください 自分の希望する回答が得られましたので、解決といたします teamikl様 有難うございました もうしばらく、開けておきます。
teamikl

2021/05/26 12:07

grid() での配置の場合、 「中に配置されたウィジェットのwidth」 と「grid のセルの width」があり、 質問のコードの場合は、ウィジェットのwidth ではなく、後者を変更する必要があります。 (結果的に、ウィジェットのwidth が狭まりますが、 直接 width を指定することは出来ないという意図の説明です) - after() は、指定ミリ秒後に関数を実行するタイマー関数です。 - 横幅の値を小さくしながら animation() を呼んでいます。  grid_columnconfigure で minsize を時間経過で徐々に小さくする - 最後(minsize==0)まで到達すると、grid_forget で非表示にする。 >pythonにはコントロールアニメーションに特化したプラグインは 無いのでしょうか? この場合は、tcl/tk や tkinter 関連のライブラリを探す事になりますが、 自分の知る限りですが、無さそうですね。 あったとしてもユーザ規模自体が他と比べて薄く、 保守されてるかどうかが不安材料です。 tkinter 以外であれば、pythonでの選択肢は - PyQt / PySide の QML - cefpython や webview 等のブラウザ組込 (HTML5でUIを開発できるので jquery 等が使える) tkinter では、 tcl/tk の次期バージョンで svg サポートが予定されてるので、 将来的には svg animation を期待できるかなといったところですが、 現状ではタイマー(after()関数)を使い独自に実装するしかなさそうです。
teamikl

2021/05/27 00:25

jquery っぽいアニメーションのデモ https://replit.com/@MiKLTea/TkAnimation#main.py place() での移動・リサイズとメソッドチェイン迄実装してみたけど、 CSS みたいに統一されたプロパティーの規格がないのが難点。 # コード例 label.animate({"x": 40, "y": 100, "width": 400} # リサイズしながら移動   ).animate({"y": 400}, 1500) # その後、1.5秒で y軸400まで移動 キャンバス内でのFade In/Out アニメーション https://replit.com/@MiKLTea/tkAsyncGame#main.py
shin0859

2021/05/27 00:47

teamikl様 度重なるコメント有難うございます コメント内容が、自分知識のずうーと先なので、消化不良状態です 時間を掛けて見ていきたい思います。 又 現時点でのpythonが知れて、為になりました。 もう自分への回答は十分頂きましたので、解決といたします。 teamikl様 有難うございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問