当一个 QPushButton 被点击时,它会触发两次 [英] When a QPushButton is clicked, it fires twice

查看:463
本文介绍了当一个 QPushButton 被点击时,它会触发两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个项目中使用了 PyQt5 并有以下代码片段(button 是一个 QPushButton)

I used PyQt5 for a project and have the following snippet (button is a 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 客户端,并且会在收到数据包时调用.布局有点复杂,因为我的 UI 有很多按钮,迭代它们比硬编码每个按钮更方便.

The on_receive function is connected to a soccet client and will be called wheneever a data package is received. The layout is a bit complicated because my UI has so many buttons it's handier to iterate over them than to hard-code every single one.

每当我单击按钮时,wire-up 函数都会将按钮连接到 upvote 函数,后者会创建一个 json protocl 并将其发送到套接字服务器.但是,每次点击都会两次调用连线功能.(由于调试打印命令,我确信这一点).我的程序中的发送函数中没有其他调用.

Whenever I click the button, the wire-up function wires the button to the upvote function, which creates a json protocl and sends it to the socket server. However, the wireup-function is called twice per click. (I am certain of this because of the debug print commands). There is no other call in the send function in my program.

我推测这可能是由于 clicked.connect 的工作方式(也许它会在点击释放时触发).

I speculate that this might be due to how clicked.connect works (maybe it fires upon click and release).

我使用 QtDesigner 创建 UI 并在我的 main.py

I used the QtDesigner to create the UI and loaded the .uic in my main.py

推荐答案

每次从 socket 接收到任何东西

Every time you receive anything from socket you do

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

并在 self.wire_up_button 中连接到按钮点击事件.请注意,self.buttonArray 始终是相同的按钮列表,因此每次调用 on_receive 时,您都会为每次按钮点击添加 1 个新订阅.但是之前对按钮点击的订阅仍然存在,因此按钮点击 upvote 将使用不同的 sid 多次调用.在添加新按钮之前,您需要断开与按钮点击事件的连接:

and in self.wire_up_button you connect to button clicked event. Note, that self.buttonArray is always the same list of buttons, so every time on_receive is called you add 1 new subscription to each button click. But previous subscription to button click still exists, so on button click upvote will be called multiple times with different sid. You need to disconnect from button click event before adding new one:

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() 如果没有函数连接到点击事件会引发异常.

try ... except block is required, because button.clicked.disconnect() raises exception if no functions were connected to click event.

这篇关于当一个 QPushButton 被点击时,它会触发两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆