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

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

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

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

Python

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

Q&A

解決済

2回答

5005閲覧

【tkinter】複数選択できるCombobox

netz-eng

総合スコア105

Tkinter

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

Python

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

0グッド

0クリップ

投稿2020/11/08 12:54

Comboboxで複数選択ができるようにしたい

PythonのTkinterでGUI作成をしています。

Combobox(普段は格納されていて、下矢印ボタンを押すとリストが現れる)を使いたいのですが、項目を複数選択できるようにしたいと思っています。

どなたか、方法をご存じありませんか?

ソースコード

https://python.keicode.com/advanced/tkinter-widget-combobox.php
↑ こちらを参考にしたコードを、以下に示します。

python

1import tkinter as tk 2import tkinter.ttk as ttk 3 4list = ["alpha", "beta", "gamma"] 5 6root = tk.Tk() 7root.title("Combobox_test") 8 9fra = ttk.Frame(root) 10fra.grid() 11 12# Combobox 13v = tk.StringVar() 14cb = ttk.Combobox(fra, textvariable=v, values=list, width=10) 15cb.set(list[0]) 16cb.bind("<<ComboboxSelected>>", lambda e: print("v=%s" % v.get())) 17cb.grid(row=0, column=0) 18 19# Button 20btn = ttk.Button(fra, text="Button", command=lambda: print("v=%s" % v.get())) 21btn.grid(row=0, column=1) 22 23root.mainloop()

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

Windows10
Python 8.3.8
tk 8.6.10

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

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

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

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

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

guest

回答2

0

ベストアンサー

複数選択したいならやはり簡単なのはListboxになると思います。
Listboxをheight=1 で作っておき、そのListboxの横に小さなボタン「▼」などをくっつけるように配置し、クリックイベントで発生する度にListboxのheightを伸ばす/1に戻す を繰り返すようにして擬似的に作るというのはどうでしょうか?

投稿2020/11/09 05:21

q_sane_q

総合スコア610

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

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

netz-eng

2020/11/09 05:49

ご回答ありがとうございます。 なるほど、高さを変更する発想はありませんでした。とても参考になります。 やはり疑似的に再現するしかありませんね……
teamikl

2020/11/09 08:04

良いアイデアですが、サイズ変更時レイアウトが動いてしまいそうなのと リストが展開されてないときに何を選択したのか確認出来ないので、 リストは表示・非表示にして、非表示時は、 ラベル等に選択された項目を、カンマ等で区切って 1行で表示した方が良いですよ。
q_sane_q

2020/11/09 08:18 編集

ラベルにカンマ区切りで表示する方式は選択肢の文字列の長さと選択数によっては横に伸びて突き抜けてしまうので万能ではないです。 そもそも展開されていない時に選択されているものがわからない、というのはプルダウンのComboBoxに複数選択が採用されない理由だと思いますね。 複数選択したいのならリスト様の形式にしておくのが結局ベターであり、他の方法にするとどこかに無理が出てくるということだと思います。 ただ今回はComboBoxめいたものが必要のようだったので擬似ウィジェットで考えてみました。 レイアウトの制御が必要なのは表示をいじる以上どれでやっても絡んできますがうまくやるしかないですね…
teamikl

2020/11/09 08:37

>そもそも展開されていない時に選択されているものがわからない、というのはプルダウンのComboBoxに複数選択が採用されない理由だと思いますね。 これには同意です。 UIとして、複数選択されているか解らないというのは問題点。 「ラベルにカンマ区切り」は、一例でして、 選択された項目の表示方法は、内容に応じて工夫の余地があります。 省略表記等で、他にも選択された項目があり、全てを見るには詳細をという形を取ります。 Tkinter ではありませんが、Multiple Select のデモ https://material-ui.com/components/selects/#multiple-select
q_sane_q

2020/11/09 08:47

まあ私は質問した本人ではないのでわからないですが、わざわざプルダウン形式を選ぶわけなので、「求めるUI」として 「何が選択されているか見える」より「非活性時にはY軸方向に1行分のコンパクトに収まる」が優先であると判断したのですが そこんとこどうなんでしょうね?>質問者様 個人的に横スクロールが入るのは苦手ですが、テキストボックスをreadonlyで使うのもアリかもしれないですね。
teamikl

2020/11/09 08:48

>ただ今回はComboBoxめいたものが必要のようだったので擬似ウィジェットで考えてみました。 > レイアウトの制御が必要なのは表示をいじる以上どれでやっても絡んできますがうまくやるしかないですね… 実装の手間を考えると、height変更で疑似的にという案は良いと思います。 (コメントより、Comboboxの直接入力は不要なようなので) レイアウトに関しては、他のレイアウトへ影響させない為に ポップアップ表示のような形での実装等が考えられます。 こちらは、もう一手間掛けられるなら…といったとこですね。
q_sane_q

2020/11/09 08:56

レイアウト制御で一番かんたんなのは、プルダウンメニュー(本物)が基本他のウィジェットより上に被さるのを再現して、雑ですが実装時に一番最後に書いておくとか、展開時にliftで上に持ち上げることだと思います。 ウィジェットのサイズ・位置操作は時々やるのですが、何か他に良さげな案があったら助かりますね。
teamikl

2020/11/09 10:29

コメント分散してしまった為、入れ違いになってしまいました。 実装の手間等も含めて判断となると、当人の判断が必要で 求めるUIに関しても、いろいろな状況・条件がありそうですが、 非活性時の表示に関しては、少なくとも既知の問題で改善可能な点だと思います。 >個人的に横スクロールが入るのは苦手ですが、 スクロールで全項目表示させるのではなく、 項目が多い場合には末尾を3点リード等で省略表示し 「省略された情報があることを示す」 (「続きを読む」「詳細を表示」といったのと同様) 画面サイズやレイアウトといった制約の中で、 表現する手段として知られています。 > 何か他に良さげな案があったら助かりますね。 プルダウンメニューとしては、Menubutton があります が、そのまま使うのは、恐らく適してない為、 簡単な方法ではなくなりますが、実装案の一つとして - 「▼」のボタンに tkinter.Menubutton を使い、 - 複数選択なので メニューの add_checkbutton で選択枝を追加。 - 選択された結果をラベルに反映
q_sane_q

2020/11/09 11:00

>項目が多い場合には末尾を3点リード等で省略表示し そうですね、なんかあれは表示するものが横に長くなってきたときによく使うので(そしてユーザの要望で横に長くなりがちなので)飽きるほどよく作りますね。 ただ論点がすれ違ったまま話を進めてしまって申し訳ないです 私は最初から「何が(何かが)選択されていることを視覚的に表示する」ことは考えていません。 質問の原点が「Comboboxを使いたい」「複数選択可能にしたい」なので「Comboboxの機能(っぽい機能)を使う」「(ListboxがあるのにComboboxを使いたい理由として)Comboboxの表示以外に(以上に)何かの表示幅を取りたくない」を要件として考えています。 自分でUI要件から設計していいなら、確かに選択されているものが何かはわかりたいので表示する機構を追加しますね。 ごめんなさい嘘です。 その場所にそれを表示するだけの縦幅を使えるということなので、最初から複数行スクロールバー有の普通のListを使います。(とはいえListの複数行は4、5行以上は表示したいので結構場所取るのが考えどころ)
netz-eng

2020/11/10 01:40

反応が遅くなり、申し訳ありません。 お二方とも、熱い議論を交わしてくださってありがとうございます! 順番にご返答させていただくと、 ①>「何が選択されているか見える」より「非活性時にはY軸方向に1行分のコンパクトに収まる」が優先であると判断したのですが  これは仰るとおりです。勿論見えるに越したことはないのですが、GUI画面のサイズ上、非活性時にはコンパクトになっていてほしいです。 ②リストに格納する項目一つ一つは短い単語のため、三点リーダ等の省略表示は必要ありません。  ただ、リストの項目数が多くなりそうなので、スクロールバーは実装できれば、と思います。 ③> 実装案の一つとして  > - 「▼」のボタンに tkinter.Menubutton を使い、  > - 複数選択なので メニューの add_checkbutton で選択枝を追加。  > - 選択された結果をラベルに反映  今までメニューボタンは使ったことがありませんでしたが、見た目的には自分の実現したいものに近いかもしれません。  教えていただいたことを参考に、とりあえずはListBoxを基準にしてみようかと思います。  ボタン呼び出しで高さ変更とスクロールバー表示をし、もう一度押すと元に戻る形が実装できれば満足です。  もしその方法でうまくいかなければ、B案としてメニューボタンを用いた方法を模索してみようと思います。
guest

0

ttk.Combobox は複数選択に対応してません。

  • Combobox の入力部分は Entry なので単一の値しか持てません。

 複数の値を表現するにする場合は、何かで区切る等の対応が必要です。

 Listbox 自体は、-selectmode multiple を指定で複数選択可能ですが、
オプションを渡す手段がありません。

仮に複数選択が出来たところで、
Comboboxでは、直接入力する場合に困ることになります。
(その為、大抵のGUIのコンボボックスでは、複数選択はサポートされません)


直接入力が不要であれば、
Listbox で複数選択用のウィジェットを構築。

直接入力で任意の値を追加したい場合は、
Listboxをダイアログもしくはポップアップで表示し、
リストへの選択項目の追加欄を設ける事になります。

投稿2020/11/08 16:02

編集2020/11/08 16:03
teamikl

総合スコア8760

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

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

netz-eng

2020/11/09 04:34

度々ご回答ありがとうございます! 自分の実現したいものは、 ・複数選択可能 ・矢印を押すと現れる(ドロップダウン)リスト なので、直接入力の機能は必要ありません。 またGUIの仕様上、ダイアログ表示は避けたいと思っています。 複数選択できるリストボックスについては、幾つかのサイトを参考に実装に至っているのですが、 ドロップダウン機能は中々例が見当たりません。 もし参考になりそうなコード、サイト、キーワード等あれば、教えていただけると嬉しいです。
teamikl

2020/11/09 08:49 編集

ドロップダウン機能については、 私の回答内のリンクが、ttk.Combobox 内部で Listbox をドロップダウンで表示してる部分のソースコード(但し TCL言語)です。 Python/tkinter での情報はなさそうなので、代案として 簡易的な方法では、place で配置、place_forget で非表示で実現できます。 - 表示する座標は、動的に計算する必要があり。 - 制限として、ウィンドウ枠の外への描画は出来ません。
netz-eng

2020/11/10 01:05

ありがとうございます。 TCL言語は全く触れたことがないので、まずはplace_forgetから調べてみようと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問