2017-10-14 16 views
1

を発射、私はプロジェクトのためPyQt5を使用して、次のスニペット(buttonがのQPushButtonある)、それは二回

def on_receive(self, query): 
    print("receiving", query) 
    datapackages = json.loads(query) 

    for button, datapackage in zip(self.buttonArray, datapackages): 
     self.wire_up_button(datapackage, button) 

def wire_up_button(self, datapackage, button): 
    title, songid = datapackage["title"], datapackage["songid"] 
    button.setText(title + " (" + str(datapackage["votes"]) + ")") 
    button.clicked.connect(lambda: self.upvote(songid)) 

def upvote(self, sid): 
    text = '{"action":"upvote", "value":"' + sid + '"}\n' 
    print(text) 
    self.send(text) 

def send(self, text): 
    print("Sending") 

on_receive機能を持っているsoccetクライアントに接続されており、wheneever呼び出されますデータパッケージが受信される。レイアウトには少し複雑です。なぜなら、UIには非常に多くのボタンが用意されており、1つ1つをハードコードするのではなく、繰り返し処理するほうが手軽だからです。

ボタンをクリックするたびに、ワイヤーアップ機能がボタンをupvote関数にワイヤリングし、json protoclを作成してソケットサーバーに送信します。ただし、ワイヤーアップ機能はと2回、と表示されます。 (私はデバッグ印刷コマンドのためにこれを確信しています)。私のプログラムのsend関数には他の呼び出しはありません。

これはclicked.connectがどのように機能するかによって変わっていると推測しています(のリリースで発生する可能性があります)。

私はUIを作成するためにQtDesignerを使用して、私のmain.py

+0

あなたはどこに 'connect'シグナルラインがあるかのように、より多くのコンテキストを追加できますか? 'songid'を見ることによって、それは関数の中にあるようです。 – PRMoureu

+1

@PRMoureu私はそうしました、それは少し起こっていることを難読化するかもしれません。私は可能な限り読みやすくするために最善を尽くしました... – Narusan

+1

upvote()は同じsidで呼び出されますか?同じボタンに対してwire_up_buttonを2回も呼び出さないことは確かですか? oh、wire_upが2回呼び出されます。 – ingvar

答えて

1

にあなたが

for button, datapackage in zip(self.buttonArray, datapackages): 
    self.wire_up_button(datapackage, button) 

を行うと、self.wire_up_buttonにボタンクリックイベントに接続しますが、ソケットから何かを受け取るたびに.uicをロードしました。 self.buttonArrayは常に同じボタンのリストなので、on_receiveが呼び出されるたびに、各ボタンクリックに1つの新しいサブスクリプションを追加することに注意してください。しかし、ボタンクリックに対する以前のサブスクリプションは依然として存在するので、upvoteボタンをクリックすると、異なるsidの複数回呼び出されます。あなたは、新しいものを追加する前に、ボタンのクリックイベントから切断する必要があります。

def wire_up_button(self, datapackage, button): 
    try: 
     button.clicked.disconnect() 
    except: 
     pass 
    title, songid = datapackage["title"], datapackage["songid"] 
    button.setText(title + " (" + str(datapackage["votes"]) + ")") 
    button.clicked.connect(lambda: self.upvote(songid)) 

try ... exceptブロックが必要とされ、何の機能がイベントをクリックして接続しなかった場合button.clicked.disconnect()は例外を発生させているため。