2009-06-30 11 views
2

コンテキストメニュで使用するシグナルの量を減らそうとしています。このメニューは、プログラムの動作モードを切り替える動作で構成されているため、スロットで実行される操作は非常に簡単です。 QMenuのマニュアル::トリガー、PyQt:シグナルを1つのスロットに集約する

通常の引用、あなたは、独自のカスタムスロットに各メニューアクションのトリガー()信号を接続し、時にはあなたは、とき例えば、単一のスロットに複数のアクションを接続することになるでしょう「左揃え」、「中央」、「右揃え」など、密接に関連した一連のアクションがあります。

しかし、私はこれを達成する方法を理解することができず、ドキュメントはこれ以上詳細には入りません。
メニューactionMenuactionOpMode1actionOpMode2のアクションがあり、スロットがsetOpModeであるとします。私はsetOpModeを、何らかのアクションがトリガーされたかどうかに関係するパラメータで呼び出すようにします。

QObject.connect(self.actionMenu, SIGNAL('triggered(QAction)'), self.setOpMode) 

しかし、私もそれがactionMenuはいわば、「トリガー感じない」んことを示唆しているsetOpModeを呼び出すためにやったことがなかった:私は、このテーマに様々な順列を試してみました。 this SO question

、lamdbasで行うことができることを示唆していますが、この:

QObject.connect(self.actionOpMode1, SIGNAL('triggered()'), lambda t: self.setOpMode(t)) 

"<lambda>() takes exactly 1 argument (0 given)"を与えます。私はこれがどのように動作するはずかを本当に理解しているとは言えないので、clicked()からtriggered()に移動するときに何か問題が起きた可能性があります。

どうやってですか?

答えて

4

QObject.Senderは、溶液の1、ではないがきれいなものです使用。

QSignalMapperを使用すると、信号を発信したオブジェクトに値をきれいに関連付けることができます。

+0

+1、QSignalMapperはこの目的のためにはっきりと設計されています。 –

+0

-1 PythonでQSignalMapperを使用する必要はありません。 –

1

QObject::sender()を使用して、どのQActionが信号を放出したかを知ることができます。

だからあなたのスロットは、次のようになります。

def triggered(self): 
    sender = QtCore.QObject.sender() 

    if sender == self.actionOpMode1: 
     # do something 
    elif sender == self.actionOpMode2: 
     # do something else 

を他に何が起こっているかについてはSO何それがないことはので、デフォルト値を持つ一つのパラメータを持つラムダを作成している、あなたは、ラムダと述べた質問

self.connect(self.actionOpMode1, QtCore.SIGNAL('triggered()'), lambda who="mode1": self.changeMode(who)) 
self.connect(self.actionOpMode2, QtCore.SIGNAL('triggered()'), lambda who="mode2": self.changeMode(who)) 

そして、このようなメンバ関数があります:

def changeMode(self, who): 
    if who == "mode1": 
     # ... 
    elif who == "mode2": 
     # ... 
をあなたの例にそれを適用するために、あなたはこのような何かをする必要があると思います

個人的には、最初のアプローチがよりクリーンで見やすくなりました。

+1

connect()は受信者の参照カウントをインクリメントしません。あなたは余分な参照を保持しない限り、接続でラムダを使用することはできません。 –

2

私は、このアプローチを使用します。

from functools import partial 

def bind(self, action, *params): 
    self.connect(action, QtCore.SIGNAL('triggered()'), 
       partial(action, *params, self.onMenuAction)) 

def onMenuAction(self, *args): 
    pass 


bind(self.actionOpMode1, 'action1') 
bind(self.actionOpMode2, 'action2') 
関連する問題