2016/11/19(土) [n年前の日記]
#2 [python] PySideでカスタムダイアログを作って入力値を取得
お絵かきアプリモドキで、キャンバスの新規作成時、サイズを入力したいなと。ダイアログを開いて、数値を入力させて、みたいな。
何を表示すればいいんだろう。ダイアログを開きたいのだから、QDialog かな。
ググってたら、以下のページに遭遇。
_python - How can I show a PyQt modal dialog and get data out of its controls once its closed? - Stack Overflow
なるほど…。こういう風に書けばいいのか。
こんな感じかな。
_qdialog_test.py
それらしく動いてる、ように見える。
QDialog を使って自作したダイアログの、OK/キャンセルボタンは、以下のように書けば用意できるみたいだなと。 _QDialogButtonBox を使うっぽい。
ダイアログを開く時は、exec_() を呼ぶようで。
前述のスクリプトの中では return (w, h, result == QDialog.Accepted) と書いてるけど、OKボタンが押されたら結果として QDialog.Accepted が返ってくるから、ソレと比較することで True / False に変換して結果を返しているのだろう。呼び出した側は、3番目の返り値が True か False かで、OKが押されたか、キャンセルが押されたかを判別すればいい。
何を表示すればいいんだろう。ダイアログを開きたいのだから、QDialog かな。
ググってたら、以下のページに遭遇。
_python - How can I show a PyQt modal dialog and get data out of its controls once its closed? - Stack Overflow
なるほど…。こういう風に書けばいいのか。
こんな感じかな。
_qdialog_test.py
u""" PySide + QDialogのテスト. カスタムダイアログを表示して入力値を取得する例. 動作確認環境 : Windows10 x64 + Python 2.7.12 + PySide 1.2.4 """ import sys from PySide.QtCore import * # NOQA from PySide.QtGui import * # NOQA class CanvasSizeInputDialog(QDialog): u"""キャンバスサイズ入力ダイアログ.""" DEF_W = 256 DEF_H = 256 def __init__(self, *argv, **keywords): """init.""" super(CanvasSizeInputDialog, self).__init__(*argv, **keywords) self.setWindowTitle("Input new canvas size") # スピンボックスを用意 self.input_w = QSpinBox(self) self.input_h = QSpinBox(self) self.input_w.setRange(1, 8192) # 値の範囲 self.input_h.setRange(1, 8192) self.input_w.setFixedWidth(80) # 表示する横幅を指定 self.input_h.setFixedWidth(80) self.input_w.setValue(CanvasSizeInputDialog.DEF_W) # 初期値を設定 self.input_h.setValue(CanvasSizeInputDialog.DEF_H) # ダイアログのOK/キャンセルボタンを用意 btns = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject) # 各ウィジェットをレイアウト gl = QGridLayout() gl.addWidget(QLabel("Input new canvas size", self), 0, 0, 1, 4) gl.addWidget(self.input_w, 1, 0) gl.addWidget(QLabel("x", self), 1, 1) gl.addWidget(self.input_h, 1, 2) gl.addWidget(btns, 2, 3) self.setLayout(gl) def canvas_size(self): u"""キャンバスサイズを取得。(w, h)で返す.""" w = int(self.input_w.value()) h = int(self.input_h.value()) return (w, h) @staticmethod def get_canvas_size(parent=None): u"""ダイアログを開いてキャンバスサイズとOKキャンセルを返す.""" dialog = CanvasSizeInputDialog(parent) result = dialog.exec_() # ダイアログを開く w, h = dialog.canvas_size() # キャンバスサイズを取得 return (w, h, result == QDialog.Accepted) class MyWidget(QWidget): u"""メインウインドウ相当.""" def __init__(self, *argv, **keywords): """init.""" super(MyWidget, self).__init__(*argv, **keywords) self.btn = QPushButton("Open Dialog", self) self.lbl = QLabel("Ready", self) # レイアウト l = QVBoxLayout() l.addWidget(self.btn) l.addWidget(self.lbl) self.setLayout(l) # ボタンを押したらキャンバスサイズ入力ダイアログを開く self.btn.clicked.connect(self.open_input_dialog) def open_input_dialog(self): u"""キャンバスサイズ入力ダイアログを開いて値を取得.""" w, h, result = CanvasSizeInputDialog.get_canvas_size(self) if result: self.lbl.setText("Ok. %d x %d" % (w, h)) else: self.lbl.setText("Cancel.") if __name__ == '__main__': app = QApplication(sys.argv) w = MyWidget() w.show() sys.exit(app.exec_())
それらしく動いてる、ように見える。
QDialog を使って自作したダイアログの、OK/キャンセルボタンは、以下のように書けば用意できるみたいだなと。 _QDialogButtonBox を使うっぽい。
# ダイアログのOK/キャンセルボタンを用意 btns = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) btns.accepted.connect(self.accept) btns.rejected.connect(self.reject)accepted とか rejected とか、そのあたりがOKだのキャンセルだのと関係してるのだろうなと。
ダイアログを開く時は、exec_() を呼ぶようで。
dialog = CanvasSizeInputDialog(parent) result = dialog.exec_() # ダイアログを開くOK/キャンセルボタンを用意した場合は、結果として、QDialog.Accepted か QDialog.Rejected が返ってくる模様。 _QDialog - PySide v1.0.7 documentation に、それらしいシンボルも見えるし。
前述のスクリプトの中では return (w, h, result == QDialog.Accepted) と書いてるけど、OKボタンが押されたら結果として QDialog.Accepted が返ってくるから、ソレと比較することで True / False に変換して結果を返しているのだろう。呼び出した側は、3番目の返り値が True か False かで、OKが押されたか、キャンセルが押されたかを判別すればいい。
[ ツッコむ ]
以上です。