試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

「CLIとGUIのもう一つの架け橋」kdialog

GNOMEにはzenityというコマンドがあり、CLIシェルやシェルスクリプト上から各種ダイアログを表示して、ユーザの操作により出力と戻り値が得られるのだが、KDEにも同様のツールkdialogがある。
zenityと共通した機能のものもあるが、扱い方が異なったり、どちらかでのみ使用できる種類のダイアログがあったりする。
kdialogはバリエーションが豊富で、ここで紹介していないもの*1もある。
関連記事:

今回の記事の構成は、上のzenityのときのものと近いものになるようにした。

実行方法

$ kdialog [種類指定オプション] ([共通オプション...] [種類固有オプション...])

詳細は

$ kdialog --help

を参照。

実行例

1行テキスト入力
$ o=$(kdialog --inputbox "テキスト入力" "文字列"); echo "戻り値:'$?' 出力:'$o'"
エラー
$ kdialog --title "エラー" --error "メッセージ"
$ kdialog --title "謝るエラー" --sorry "メッセージ"

--sorryオプションでは、謝る*2ダイアログが作成できる。

情報
$ kdialog --title "情報" --msgbox "メッセージ"
ファイル選択

拡張子などのパターンもしくはMIMEタイプ指定によるフィルタができる。
--getopenfilenameなどのオプションの後ろに付く引数は、はじめに表示される階層とフィルタパターンになる。

$ o=$(kdialog --title "ファイル選択" --getopenfilename /usr/share/pixmaps "image/png image/x-xpixmap"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "ファイル選択(複数)" --getopenfilename /usr/share/pixmaps "image/png image/x-xpixmap" --multiple); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "ファイル選択" --getopenfilename /lib "*.so|Shared Object file (*.so)"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "ファイル選択" --getsavefilename ${HOME} "*.txt"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title="ディレクトリ選択" --getexistingdirectory ${HOME}); echo "戻り値:'$?' 出力:'$o'"
リスト選択

ラジオ/チェックリストでは、各項目は「返る値/選択肢の文字列/初期値(onもしくはoff)」の3つの引数でまとまりを持っている。

$ o=$(kdialog --title "リスト" --menu "質問" A "選択肢A" B "選択肢B"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "コンボボックスのリスト" --combobox "質問" A B --default A); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "ラジオリスト" --radiolist "質問" A "選択肢A" on  B "選択肢B" off  C "選択肢C" off); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "チェックリスト" --checklist "質問" A "選択肢A" on  B "選択肢B" off  C "選択肢C" on); echo "戻り値:'$?' 出力:'$o'"
進行状況バー

KDE3版とKDE4版で使用方法が異なる。KDE3版は
http://developer.kde.org/documentation/tutorials/kdialog/x85.html
を参照。KDE4版ではD-Bus*3を使用するようになったのだが、Web上の文書が見当たらず、ソース中のデモファイルを参考にした。

$ ref=$(kdialog --title "進行状況" --progressbar "経過の表示" 100)
$ for ((i = 0; i <= 100; i += 10)); do qdbus ${ref} Set org.kde.kdialog.ProgressDialog value $i; sleep 0.5; done
$ qdbus ${ref} org.kde.kdialog.ProgressDialog.close
$ unset ref

デモのファイルも転載(コマンド部分のみ一部修正)。
[転載]ファイル名: kdebase-4.0.3/apps/kdialog/progressdemo

dbusRef=`kdialog --geometry 300x200+100-100 --progressbar "Initialising" 6`
qdbus $dbusRef Set org.kde.kdialog.ProgressDialog value 1
qdbus $dbusRef setLabelText "Thinking really hard"
sleep 2
qdbus $dbusRef Set org.kde.kdialog.ProgressDialog value 2
sleep 2
qdbus $dbusRef setLabelText "Thinking some more"
qdbus $dbusRef Set org.kde.kdialog.ProgressDialog value 3
sleep 2
qdbus $dbusRef Set org.kde.kdialog.ProgressDialog value 4
sleep 2
qdbus $dbusRef setLabelText "Finishing up"
qdbus $dbusRef Set org.kde.kdialog.ProgressDialog value 5
sleep 1
qdbus $dbusRef Set org.kde.kdialog.ProgressDialog value 6
sleep 1
qdbus $dbusRef org.kde.kdialog.ProgressDialog.close

上の例ではキャンセルできないが、下の例ではキャンセルできる。状態を毎秒確認してループする使い方をするようだ。
[転載]ファイル名: kdebase-4.0.3/apps/kdialog/progresscanceldemo

dbusRef=`kdialog --progressbar "Press Cancel at Any time" 10`
qdbus $dbusRef org.kde.kdialog.ProgressDialog.showCancelButton true

until test "true" = `qdbus $dbusRef org.kde.kdialog.ProgressDialog.wasCancelled`; do
  sleep 1
  inc=$((`qdbus $dbusRef org.freedesktop.DBus.Properties.Get org.kde.kdialog.ProgressDialog value` + 1))
  qdbus $dbusRef org.freedesktop.DBus.Properties.Set org.kde.kdialog.ProgressDialog value $inc;
done

qdbus $dbusRef org.kde.kdialog.ProgressDialog.close
質問

バリエーションが多い。

$ o=$(kdialog --title "2択質問" --yesno "質問内容"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "3択質問・キャンセル付き" --yesnocancel "質問内容"); echo "戻り値:'$?' 出力:'$o'"
警告

警告ダイアログでは選択肢が出る。
参考として、zenityのバージョン2.18以上では、質問ではなくメッセージ表示のみとなっている。

$ o=$(kdialog --title "2択質問・警告" --warningyesno "質問内容"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "3択質問・キャンセル付き・警告" --warningyesnocancel "質問内容"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(kdialog --title "2択質問・続行とキャンセル・警告" --warningcontinuecancel "質問内容"); echo "戻り値:'$?' 出力:'$o'"
テキストデータの表示

標準入力を処理できない仕様?のため、コマンドの出力を表示したい場合、コマンド行の中に結果を渡す*4か、あるいは一度中間ファイルに書き出して読み込ませる。

$ kdialog --title "テキスト" --textbox textfile.txt 500 300
$ kdialog --title "テキスト" --textinputbox "テキスト表示" "$(dmesg)" 500 300
$ dmesg > /tmp/cmd.txt; kdialog --title "テキスト" --textbox /tmp/cmd.txt 500 300; rm /tmp/cmd.txt -f
通知

表示時間を後ろに渡して指定する。下の例では10秒。

$ kdialog --title "通知" --passivepopup "メッセージ" 10

使用したバージョン:

  • kdialog 4.0.3

*1:URL入力、パスワード入力、設定保存(「今後は表示しない/尋ねない」)など

*2:--titleオプションでタイトルを指定しない場合、ウィンドウタイトルが「すみません」になる

*3:アプリケーションどうしでデータをやりとりするのに使用されるもの(デーモンとツール)で、システムとのやりとりも行われる

*4:psコマンドなどでコマンド実行結果部分が見えてしまい、コマンド行自体も長くなる