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が押されたか、キャンセルが押されたかを判別すればいい。
[ ツッコむ ]
以上です。