当一个 QPushButton 被点击时,它会触发两次 [英] When a QPushButton is clicked, it fires twice
问题描述
我在一个项目中使用了 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屋!