Signals and Slots in PySide/ja: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 1: Line 1:
'''日本語''' [[Signals and Slots in PySide|English]] [[Signals and Slots in PySide Korean|한국어]]
[[Category:LanguageBindings::PySide]]<br />[[Category:LanguageBindings::PySide Japanese]]


=PySideのシグナルとスロット=
'''日本語''' [[Signals_and_Slots_in_PySide|English]] [[Signals_and_Slots_in_PySide_Korean|한국어]]
 
= PySideのシグナルとスロット =


このページではPySideのシグナルとスロットの使い方を説明します。いわゆる新スタイルのシグナルとスロットの使い方を中心に説明しますが、参考として旧スタイルの使い方も合わせて紹介します。
このページではPySideのシグナルとスロットの使い方を説明します。いわゆる新スタイルのシグナルとスロットの使い方を中心に説明しますが、参考として旧スタイルの使い方も合わせて紹介します。


PyQtでは、新スタイルのシグナルとスロットはPyQt v4.5から導入されました。この新スタイルの目的は、PythonプログラマによりPythonicな構文を提供することです。PySideは [http://www.pyside.org/docs/pseps/psep-0100.html <span class="caps">PSEP</span> 100] ''[pyside.org]'' をこの実装のガイドラインとして使用しています。
PyQtでは、新スタイルのシグナルとスロットはPyQt v4.5から導入されました。この新スタイルの目的は、PythonプログラマによりPythonicな構文を提供することです。PySideは &quot;PSEP 100&amp;quot;:http://www.pyside.org/docs/pseps/psep-0100.html をこの実装のガイドラインとして使用しています。


==旧スタイルの方法 SIGNALとSLOT==
== 旧スタイルの方法 SIGNALとSLOT ==


''QtCore.<span class="caps">SIGNAL</span>'' と ''QtCore.<span class="caps">SLOT</span>'' マクロは、Qtのシグナル/スロット配信機構とPythonをつなぐインタフェースであり、旧スタイルのシグナル/スロットの使い方です。
''QtCore.SIGNAL (...)'' と ''QtCore.SLOT (...)'' マクロは、Qtのシグナル/スロット配信機構とPythonをつなぐインタフェースであり、旧スタイルのシグナル/スロットの使い方です。


次の例ではQPushButtonの一般的なシグナルであるclickedシグナルを使用しています。旧スタイルではマクロ経由のシグナルと接続先のスロットをオブジェクトに伝えるため、connectメソッドはpythonに馴染みにくい構文になります。
次の例ではQPushButtonの一般的なシグナルであるclickedシグナルを使用しています。旧スタイルではマクロ経由のシグナルと接続先のスロットをオブジェクトに伝えるため、connectメソッドはpythonに馴染みにくい構文になります。


==新スタイルの方法 Signal()とSlot()==
<code><br />…
 
def someFunc():<br /> print &quot;someFunc has been called!&quot;
 
 
button = QtGui.QPushButton(&quot;Call someFunc&amp;quot;)<br />QtCore.QObject.connect(button, QtCore.SIGNAL (&amp;#39;clicked()'), someFunc)
 
…<br /></code>
 
== 新スタイルの方法 Signal()とSlot() ==


新スタイルでは新しい構文を使ってシグナルとスロットを接続します。先ほどの例は次のようにすっきりと書くことができます。
新スタイルでは新しい構文を使ってシグナルとスロットを接続します。先ほどの例は次のようにすっきりと書くことができます。


===QtCore.Signal()の使い方===
<code><br />…
 
def someFunc():<br /> print &quot;someFunc has been called!&quot;
 
button = QtGui.QPushButton(&quot;Call someFunc&amp;quot;)<br />button.clicked.connect(someFunc)
 
…<br /></code>
 
=== QtCore.Signal()の使い方 ===


シグナルは ''QtCore.Sginal()'' クラスを使って定義します。シグナルのパラメータとしてPythonとCの型が指定できます。オーバーロードをする場合は、複数のパラメータをタプルやリストを使って指定します。
シグナルは ''QtCore.Sginal()'' クラスを使って定義します。シグナルのパラメータとしてPythonとCの型が指定できます。オーバーロードをする場合は、複数のパラメータをタプルやリストを使って指定します。
Line 27: Line 47:
注:シグナルは ''QObject'' を継承したクラス内でのみ定義してください。これにより、シグナル情報がQMetaObjectクラスの構造体に追加されます。
注:シグナルは ''QObject'' を継承したクラス内でのみ定義してください。これにより、シグナル情報がQMetaObjectクラスの構造体に追加されます。


===QtCore.Slot()の使い方===
=== QtCore.Slot()の使い方 ===


スロットの指定やオーバーロードには ''QtCore.Slot()'' デコレータを使います。スロットのパラメータ定義は ''QtCore.Signal()'' と同じく型を指定します。ただしオーバーロードの場合、 ''Signal()'' クラスのようにタプルやリストによるパラメータ指定は行いません。代わりにパラメータ毎に新たなデコレータを定義します。以下の例題でこの違いが明確に分かると思います。
スロットの指定やオーバーロードには ''QtCore.Slot()'' デコレータを使います。スロットのパラメータ定義は ''QtCore.Signal()'' と同じく型を指定します。ただしオーバーロードの場合、 ''Signal()'' クラスのようにタプルやリストによるパラメータ指定は行いません。代わりにパラメータ毎に新たなデコレータを定義します。以下の例題でこの違いが明確に分かると思います。
Line 33: Line 53:
また、キーワード引数も異なります。 ''Slot()'' は ''name'' 、 ''result'' の2つのキーワード引数を受けとります。 ''result'' キーワードは返却型を定義し、CとPythonの型を指定できます。 ''name'' キーワードは ''Signal()'' と同様に、未指定の場合には関数名がスロット名になります。
また、キーワード引数も異なります。 ''Slot()'' は ''name'' 、 ''result'' の2つのキーワード引数を受けとります。 ''result'' キーワードは返却型を定義し、CとPythonの型を指定できます。 ''name'' キーワードは ''Signal()'' と同様に、未指定の場合には関数名がスロット名になります。


===例題集===
=== 例題集 ===


以下の例では、PySideのシグナルとスロットの定義、および接続方法を示しています。基本的な例とより複雑な例を示します。
以下の例では、PySideのシグナルとスロットの定義、および接続方法を示しています。基本的な例とより複雑な例を示します。
Line 39: Line 59:
* 次の例は、基本的なHello Worldプログラムです。パラメータを指定せずにシグナルとスロットを接続しています。
* 次の例は、基本的なHello Worldプログラムです。パラメータを指定せずにシグナルとスロットを接続しています。


* 次の例は、引数が追加されたHello Worldプログラムの修正版です。スロットに引数が追加され、さらに新しいシグナルが作成されています。
<code><br />#!/usr/bin/env python<br /># <s>'''- coding: utf-8 <s>'''-
<br />import sys<br />from PySide import QtCore, QtGui
<br /># スロットとして使用する関数を定義します<br />def sayHello():<br /> print 'Hello world!'
<br />app = QtGui.QApplication(sys.argv)
<br />button = QtGui.QPushButton('Say hello!')
<br /># clickedシグナルとsayHelloスロットを接続します<br />button.clicked.connect(sayHello)<br />button.show()
<br />sys.exit(app.exec_())<br /></code>
<br />''' 次の例は、引数が追加されたHello Worldプログラムの修正版です。スロットに引数が追加され、さらに新しいシグナルが作成されています。
<br /><code><br />#!/usr/bin/env python<br />#</s>'''</s> coding: utf-8 <s>'''-
<br />import sys<br />from PySide import QtCore
<br /># 新たなスロットを定義します。このスロットは文字列を受け取り<br /># 名前が「saySomeWords」になります<br />&amp;#64;QtCore.Slot(str)<br />def saySomeWords(words):<br /> print words
<br />class Communicate(QtCore.QObject):<br /> # シグナルをその場で作成し、名前を「speak」とします<br /> speak = QtCore.Signal(str)
<br />someone = Communicate()<br /># シグナルとスロットを接続します<br />someone.speak.connect(saySomeWords)<br /># 「speak」シグナルを送出します<br />someone.speak.emit(&quot;Hello everybody!&quot;)<br /></code>
<br />''' 次はオーバーロードを行います。前回のプログラムを少し修正して、オーバーロードのデコレータを作ります。
<br /><code><br />#!/usr/bin/env python<br />#</s>'''- coding: utf-8 <s>'''-
<br />import sys<br />from PySide import QtCore
<br /># Cの「int」とpythonの「str」型を受け取る新たなスロットを定義します<br /># 名前は「saySomething」です<br />&amp;#64;QtCore.Slot(int)<br />&amp;#64;QtCore.Slot(str)<br />def saySomething(stuff):<br /> print stuff
<br />class Communicate(QtCore.QObject):<br /> # 2つの新しいシグナルをその場で作成します<br /> # 「int」と「str」型を持つシグナルです<br /> speakNumber = QtCore.Signal(int)<br /> speakWord = QtCore.Signal(str)
<br />someone = Communicate()<br /># シグナルとスロットを接続します<br />someone.speakNumber.connect(saySomething)<br />someone.speakWord.connect(saySomething)<br /># 2つの「speak」シグナルを送出します<br />someone.speakNumber.emit(10)<br />someone.speakWord.emit(&quot;Hello everybody!&quot;)<br /></code>
<br />''' 最後の例では、スロットとシグナルをオーバーロードし、複雑な接続と送出を行います。
<br /><code><br />#!/usr/bin/env python<br />#</s>'''- coding: utf-8 <s>*</s>
 
import sys<br />from PySide import QtCore
 
# Cの「int」とpythonの「str」型を受け取る新たなスロットを定義します
# 名前は「saySomething」です<br />&amp;#64;QtCore.Slot(int)<br />&amp;#64;QtCore.Slot(str)<br />def saySomething(stuff):<br /> print stuff
 
class Communicate(QtCore.QObject):<br /> # オーバーロードのシグナルを作成します<br /> # 「int」と「str」型の2つの型を持つシグナルです<br /> speak = QtCore.Signal((int,), (str,))


* 次はオーバーロードを行います。前回のプログラムを少し修正して、オーバーロードのデコレータを作ります。
someone = Communicate()<br /># シグナルとスロットを接続します。シグナルはデフォルトでは「int」型になります<br /># 「str」型にする場合には接続時に指定する必要があります<br />someone.speak.connect(saySomething)<br />someone.speak[str].connect(saySomething)


* 最後の例では、スロットとシグナルをオーバーロードし、複雑な接続と送出を行います。
# 異なる型を持つ「speak」シグナルを送出します
# デフォルトでは「int」型になり、「str」型を使う場合は明示的に指定します<br />someone.speak.emit(10)<br />someone.speak[str].emit(&quot;Hello everybody!&quot;)<br /></code>


==PyQtとの互換性==
== PyQtとの互換性 ==


PyQtの新スタイルとは、シグナル/スロット関数の命名規則が異なります。新スタイルのPyQtからPySideへの変換は、次のいずれかの方法で修正してください。
PyQtの新スタイルとは、シグナル/スロット関数の命名規則が異なります。新スタイルのPyQtからPySideへの変換は、次のいずれかの方法で修正してください。
<code><br />from PySide.QtCore import Signal as pyqtSignal<br />from PySide.QtCore import Slot as pyqtSlot<br /></code>


または次のようにします。
または次のようにします。


この修正によってpyqtSignal/pyqtSlotコールが、PySideのSignal/Slotコールに変換されます。
<code><br />QtCore.pyqtSignal = QtCore.Signal<br />QtCore.pyqtSlot = QtCore.Slot<br /></code>
 
===Categories:===
 
* [[:Category:LanguageBindings|LanguageBindings]]
** [[:Category:LanguageBindings::PySide|PySide]]
* [[:Category:LanguageBindings::PySide-Japanese|PySide Japanese]]

Revision as of 09:02, 24 February 2015


日本語 English 한국어

PySideのシグナルとスロット

このページではPySideのシグナルとスロットの使い方を説明します。いわゆる新スタイルのシグナルとスロットの使い方を中心に説明しますが、参考として旧スタイルの使い方も合わせて紹介します。

PyQtでは、新スタイルのシグナルとスロットはPyQt v4.5から導入されました。この新スタイルの目的は、PythonプログラマによりPythonicな構文を提供することです。PySideは "PSEP 100&quot;:http://www.pyside.org/docs/pseps/psep-0100.html をこの実装のガイドラインとして使用しています。

旧スタイルの方法 SIGNALとSLOT

QtCore.SIGNAL (...)QtCore.SLOT (...) マクロは、Qtのシグナル/スロット配信機構とPythonをつなぐインタフェースであり、旧スタイルのシグナル/スロットの使い方です。

次の例ではQPushButtonの一般的なシグナルであるclickedシグナルを使用しています。旧スタイルではマクロ経由のシグナルと接続先のスロットをオブジェクトに伝えるため、connectメソッドはpythonに馴染みにくい構文になります。

<br />

def someFunc():<br /> print &quot;someFunc has been called!&quot;



button = QtGui.QPushButton(&quot;Call someFunc&amp;quot;)<br />QtCore.QObject.connect(button, QtCore.SIGNAL (&amp;#39;clicked()'), someFunc)

<br />

新スタイルの方法 Signal()とSlot()

新スタイルでは新しい構文を使ってシグナルとスロットを接続します。先ほどの例は次のようにすっきりと書くことができます。

<br />

def someFunc():<br /> print &quot;someFunc has been called!&quot;

button = QtGui.QPushButton(&quot;Call someFunc&amp;quot;)<br />button.clicked.connect(someFunc)

<br />

QtCore.Signal()の使い方

シグナルは QtCore.Sginal() クラスを使って定義します。シグナルのパラメータとしてPythonとCの型が指定できます。オーバーロードをする場合は、複数のパラメータをタプルやリストを使って指定します。

またクラスはシグナル名を定義する名前付き引数(キーワード引数) name を持っています。キーワード name が未指定の場合、代入先の変数名がシグナル名になります。

以下の例題集で、 QtCore.Signal() の使用例をまとめています。

注:シグナルは QObject を継承したクラス内でのみ定義してください。これにより、シグナル情報がQMetaObjectクラスの構造体に追加されます。

QtCore.Slot()の使い方

スロットの指定やオーバーロードには QtCore.Slot() デコレータを使います。スロットのパラメータ定義は QtCore.Signal() と同じく型を指定します。ただしオーバーロードの場合、 Signal() クラスのようにタプルやリストによるパラメータ指定は行いません。代わりにパラメータ毎に新たなデコレータを定義します。以下の例題でこの違いが明確に分かると思います。

また、キーワード引数も異なります。 Slot()nameresult の2つのキーワード引数を受けとります。 result キーワードは返却型を定義し、CとPythonの型を指定できます。 name キーワードは Signal() と同様に、未指定の場合には関数名がスロット名になります。

例題集

以下の例では、PySideのシグナルとスロットの定義、および接続方法を示しています。基本的な例とより複雑な例を示します。

  • 次の例は、基本的なHello Worldプログラムです。パラメータを指定せずにシグナルとスロットを接続しています。
<br />#!/usr/bin/env python<br /># <s>'''- coding: utf-8 <s>'''-
<br />import sys<br />from PySide import QtCore, QtGui
<br /># スロットとして使用する関数を定義します<br />def sayHello():<br /> print 'Hello world!'
<br />app = QtGui.QApplication(sys.argv)
<br />button = QtGui.QPushButton('Say hello!')
<br /># clickedシグナルとsayHelloスロットを接続します<br />button.clicked.connect(sayHello)<br />button.show()
<br />sys.exit(app.exec_())<br />


次の例は、引数が追加されたHello Worldプログラムの修正版です。スロットに引数が追加され、さらに新しいシグナルが作成されています。


<br />#!/usr/bin/env python<br />#</s>'''</s> coding: utf-8 <s>'''-
<br />import sys<br />from PySide import QtCore
<br /># 新たなスロットを定義しますこのスロットは文字列を受け取り<br /># 名前がsaySomeWordsになります<br />&amp;#64;QtCore.Slot(str)<br />def saySomeWords(words):<br /> print words
<br />class Communicate(QtCore.QObject):<br /> # シグナルをその場で作成し名前をspeakとします<br /> speak = QtCore.Signal(str)
<br />someone = Communicate()<br /># シグナルとスロットを接続します<br />someone.speak.connect(saySomeWords)<br /># speakシグナルを送出します<br />someone.speak.emit(&quot;Hello everybody!&quot;)<br />


次はオーバーロードを行います。前回のプログラムを少し修正して、オーバーロードのデコレータを作ります。


<br />#!/usr/bin/env python<br />#</s>'''- coding: utf-8 <s>'''-
<br />import sys<br />from PySide import QtCore
<br /># Cのintとpythonのstr型を受け取る新たなスロットを定義します<br /># 名前はsaySomethingです<br />&amp;#64;QtCore.Slot(int)<br />&amp;#64;QtCore.Slot(str)<br />def saySomething(stuff):<br /> print stuff
<br />class Communicate(QtCore.QObject):<br /> # つの新しいシグナルをその場で作成します<br /> # intstr型を持つシグナルです<br /> speakNumber = QtCore.Signal(int)<br /> speakWord = QtCore.Signal(str)
<br />someone = Communicate()<br /># シグナルとスロットを接続します<br />someone.speakNumber.connect(saySomething)<br />someone.speakWord.connect(saySomething)<br /># つのspeakシグナルを送出します<br />someone.speakNumber.emit(10)<br />someone.speakWord.emit(&quot;Hello everybody!&quot;)<br />


最後の例では、スロットとシグナルをオーバーロードし、複雑な接続と送出を行います。


<br />#!/usr/bin/env python<br />#</s>'''- coding: utf-8 <s>*</s>

import sys<br />from PySide import QtCore

# Cの「int」とpythonの「str」型を受け取る新たなスロットを定義します
# 名前は「saySomething」です<br />&amp;#64;QtCore.Slot(int)<br />&amp;#64;QtCore.Slot(str)<br />def saySomething(stuff):<br /> print stuff

class Communicate(QtCore.QObject):<br /> # オーバーロードのシグナルを作成します<br /> # intstr型の2つの型を持つシグナルです<br /> speak = QtCore.Signal((int,), (str,))

someone = Communicate()<br /># シグナルとスロットを接続しますシグナルはデフォルトではint型になります<br /># str型にする場合には接続時に指定する必要があります<br />someone.speak.connect(saySomething)<br />someone.speak[str].connect(saySomething)

# 異なる型を持つ「speak」シグナルを送出します
# デフォルトでは「int」型になり、「str」型を使う場合は明示的に指定します<br />someone.speak.emit(10)<br />someone.speak[str].emit(&quot;Hello everybody!&quot;)<br />

PyQtとの互換性

PyQtの新スタイルとは、シグナル/スロット関数の命名規則が異なります。新スタイルのPyQtからPySideへの変換は、次のいずれかの方法で修正してください。

<br />from PySide.QtCore import Signal as pyqtSignal<br />from PySide.QtCore import Slot as pyqtSlot<br />

または次のようにします。

<br />QtCore.pyqtSignal = QtCore.Signal<br />QtCore.pyqtSlot = QtCore.Slot<br />