コンボボックスでリストを表示させる時、ほとんどはエントリの下側にリストが表示されます。
ただ、どういった条件で発生するかまで分かりませんが、エントリの上側にリストが表示されることがあります。
どういった条件で発生するのでしょうか?
またtkinterで上下を指定することは可能でしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
一応やってみました。解説は前の回答を参照してください。
style.configure("TCombobox", popup=1) の部分を True, False で上下指定できます。
※注意点とデメリット、tk内部の関数を上書きしているので、
Python(に付随するtcl/tk)のアップデート等により期待通りに動かなくなる可能性もあります。
調べるコスト、Tcl/Tkの学習コスト、後々の保守等を考えると、
Python上で1から期待通りの動作をするComboboxを実装した方が良いかもしれません。
python
1 2TCL_HOOK_PLACEPOPDOWN = """ 3proc ttk::combobox::PlacePopdown {cb popdown} { 4 set x [winfo rootx $cb] 5 set y [winfo rooty $cb] 6 set w [winfo width $cb] 7 set h [winfo height $cb] 8 set postoffset [ttk::style lookup TCombobox -postoffset {} {0 0 0 0}] 9 set popup [ttk::style lookup TCombobox -popup {} {0}] 10 foreach var {x y w h} delta $postoffset { 11 incr $var $delta 12 } 13 14 set H [winfo reqheight $popdown] 15 16 if {$y + $h + $H > [winfo screenheight $popdown]} { 17 set Y [expr {$y - $H}] 18 } else { 19 set Y [expr {$y + $h}] 20 } 21 if {$popup == 1} { 22 set Y [expr {$y - $H}] 23 } 24 25 wm geometry $popdown ${w}x${H}+${x}+${Y} 26} 27""" 28 29 30import tkinter as tk 31from tkinter import ttk 32 33root = tk.Tk() 34style = ttk.Style() 35style.configure("TCombobox", popup=1) 36 37cb = ttk.Combobox(root, values=["A","B","C"], style="TCombobox") 38cb.tk.eval(TCL_HOOK_PLACEPOPDOWN) 39cb.pack(fill=tk.BOTH, expand=1) 40 41root.mainloop() 42
投稿2020/03/30 16:16
編集2020/03/30 17:22総合スコア8760
0
ウィンドウがディスプレイの下の方に配置されていて、リストを下方向に出すと
画面に表示しきれないときに上向きのポップアップになります。
またtkinterで上下を指定することは可能でしょうか?
手段はあると思いますが、そういった細かな内部の制御をするのは難しくなります。
オプションで簡単に指定できるかという意味では、NOです。
Pythonのtkinterライブラリは、
tcl/tk (TCLという言語のtkライブラリ) をPythonから操る形で実装されていて、
tkinterで提供されている以外の事をしようとすると、
ライブラリ内部のtkを制御するtclでのコマンドを調べる必要が出てきます。
- python の tkinter/ttk.py の Combobox クラスを調べても情報は何もありません。
- tck/tk の library/ttk/combobox.tcl を調べます。
ポップダウンの座標を計算している部分のコード抜粋
※ Pythonではありません。TCLという言語です。
tcl
1## PlacePopdown -- 2# Set popdown window geometry. 3# 4# @@@TODO: factor with menubutton::PostPosition 5# 6proc ttk::combobox::PlacePopdown {cb popdown} { 7 set x [winfo rootx $cb] 8 set y [winfo rooty $cb] 9 set w [winfo width $cb] 10 set h [winfo height $cb] 11 set postoffset [ttk::style lookup TCombobox -postoffset {} {0 0 0 0}] 12 foreach var {x y w h} delta $postoffset { 13 incr $var $delta 14 } 15 16 set H [winfo reqheight $popdown] 17 if {$y + $h + $H > [winfo screenheight $popdown]} { 18 set Y [expr {$y - $H}] 19 } else { 20 set Y [expr {$y + $h}] 21 } 22 wm geometry $popdown ${w}x${H}+${x}+${Y} 23} 24
上か下かを決めているのは、
tcl
1 set H [winfo reqheight $popdown] 2 if {$y + $h + $H > [winfo screenheight $popdown]} { 3 set Y [expr {$y - $H}] 4 } else { 5 set Y [expr {$y + $h}] 6 }
リストの縦幅(H)とスクリーンの縦幅を調べて、
その後の set Y
で表示する Y座標で上か下かを決めています。
スタイルを使って座標を指定
set postoffset [ttk::style lookup TCombobox -postoffset {} {0 0 0 0}]
という部分がありますが、ここに ttk.Style を通じてオプションを渡せます。
但し、座標はリストの縦幅に応じて自分で計算する必要あり。(下のサンプルコードでは固定値)
ちょっとした簡単な事でも、コードは複雑になりがちです。
python
1import tkinter as tk 2from tkinter import ttk 3 4root = tk.Tk() 5style = ttk.Style() 6style.configure("TCombobox", postoffset=(0,-60,0,0)) 7comboBox = ttk.Combobox(root, values=["A","B","C"], style="TCombobox") 8comboBox.pack(fill=tk.BOTH, expand=1) 9root.mainloop()
投稿2020/03/30 15:24
編集2020/03/30 16:53総合スコア8760
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。