2009-07-08 6 views
10

私は文字列のリストを持っていて、それらの文字列ごとにメニュー項目を作成したいと思っています。ユーザーが項目の1つをクリックすると、文字列を引数として常に同じ関数が呼び出されます。いくつかしようと研究した後、私はこのような何かを思い付いた:「項目3」の代わりに、対応する1:文字列のリストからPyQtメニューを作成する

import sys 
from PyQt4 import QtGui, QtCore 

class MainWindow(QtGui.QMainWindow): 
    def __init__(self): 
     QtGui.QMainWindow.__init__(self) 
     self.menubar = self.menuBar() 
     menuitems = ["Item 1","Item 2","Item 3"] 
     menu = self.menubar.addMenu('&Stuff') 
     for item in menuitems: 
      entry = menu.addAction(item) 
      self.connect(entry,QtCore.SIGNAL('triggered()'), lambda: self.doStuff(item)) 
      menu.addAction(entry) 
     print "init done" 

    def doStuff(self, item): 
     print item 

app = QtGui.QApplication(sys.argv) 
main = MainWindow() 
main.show() 
sys.exit(app.exec_()) 

さて問題は、メニュー項目のそれぞれが同じ出力を印刷することです。どのように私がこの権利を得ることができるかについての私の考えに感謝しています。ありがとう。

答えて

23

あなたはそれを早く(デフタイムで)好きなのですが。だから、あなたが今持っている場所:

for item in menuitems: 
     entry = menu.addAction(item) 
     self.connect(entry,QtCore.SIGNAL('triggered()'), lambda: self.doStuff(item)) 

が代わりにしてみてください:(ここではitem 1など)のデフォルト値はDEF-時に一度、すべてのために計算されますので、

for item in menuitems: 
     entry = menu.addAction(item) 
     self.connect(entry,QtCore.SIGNAL('triggered()'), lambda item=item: self.doStuff(item)) 

これは、バインディングを「予想し」 。 -

functools.partial(self.doStuff, item)(最上部にimport functools)を使用することもできます。これはもう1つの優れた解決策ですしかし、私は、最も単純な(そして最も一般的な) "議論のための偽のデフォルト値"イディオムに行くと思う。

+1

@Alex:+1 !!!それは午前中に私を悩ませている!ラムダx = x:func(x)FTW :) –

+0

優れた答え!また、新しい接続構文でも動作します: 'entry.triggered.connect(lambda item = item:self.doStuff(item))' – Leistungsabfall

2

これはうまくいくはずですが、私が今思い出すことのできない良い方法があると確信しています。

def do_stuff_caller(self, item): 
    return lambda: self.doStuff(item) 

... 
self.connect(entry, QtCore.SIGNAL('triggered()'), self.do_stuff_caller(item)) 

編集: 短いバージョンは、まだそれは私が考えている...または多分それは別の言語にあったものではありませんか?バインディングは、呼び出し時に遅く(字句のルックアップです) - あなたは、多くの場合、そうでないかもしれない完全にpedantically-正しく(と呼ばれているもの;-) Pythonで「スコープの問題」として会っている:)

(lambda x: lambda self.do_stuff(x))(item)
関連する問題