LoginSignup
9
9

More than 5 years have passed since last update.

PySideのスロットを定義する際の注意

Last updated at Posted at 2013-06-27

注意

(2018/08/25)
Qt for Python 5.11.2ではこの事象は修正済とのコメントを頂きました。そのため、以下の内容は古くなっています。


自分用メモ. 後でもうちょっと詳細に書くかも.

PySide(というかおそらくQt)には,GUIイベントをハンドルするための仕組みとして,「シグナル」と「スロット」という概念を持つ.

以下は,'clicked'というシグナルに,自分で定義したbutton_clickedメソッドをスロットとして結びつけている.

ex1
class Hoge(QWidget):
    def __init__(self):
        super(Hoge, self).__init__()

        self.button1 = QPushButton('Button1', self)
        self.button1.clicked.connect(self.button_clicked)

    def button_clicked(self):
        sender = self.sender()
        self.window().statusBar().showMessage(sender.text() + ' was clicked')

'clicked'というのは文字通り,クリックイベントと結びついている.
該当するオブジェクト(上記例ではボタン)がクリックされると,結びつけたスロット(button_clicked)がコールされるという寸法だ.

で,ここからが今日少しはまった事例.
スロットとして指定したメソッド内で,self.sender()をコールすることにより,イベントの発生元オブジェクトを指定できる.
その際,スロットとして指定するメソッドがネームマングリングされている場合,self.sender()がNoneを返してしまい,発生元オブジェクトが上手く取得できなかった.

ex2
class Hoge(QWidget):
    def __init__(self):
        super(Hoge, self).__init__()

        self.button1 = QPushButton('Button1', self)
        self.button1.clicked.connect(self.button_clicked)

        self.button2 = QPushButton('Button1', self)
        self.button2.clicked.connect(self.__button_clicked)

    # ネームマングリングしない
    def button_clicked(self):
        sender = self.sender()
        print sender.text()

    # ネームマングリングする
    def __button_clicked(self):
        sender = self.sender()
        print sender.text()

以下がその時の出力.

Button1 (Button1は発生元が取得できている)
Traceback (most recent call last): (Button2は上手くできない)
  File "sandbox/myevent.py", line 77, in __button_clicked
    print sender.text()
AttributeError: 'NoneType' object has no attribute 'text'

いまいち原因が追いきれていないが,ひとまずスロットに指定する場合はネームマングリングしないようにしておこう...

9
9
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9