单击一个按钮多次触发信号而不是一次

One button click fires signal multiple times instead of once

我正在使用 pyside 和 sqlalchemy 作为联系信息数据库。

sqlalchemy 的设置非常标准,除了当我使用 sessionmaker() 创建 session 时,我设置了 expire_on_commit = False.

为了能够在一次会议中创建一个新的 session,我使用了一种刷新按钮。问题是每次我使用刷新按钮时,当我尝试添加一个新的 line/entry 时,我会得到 2 或 4 个额外的条目(单击一次),而如果一个被删除,所有 "copies"也被删除了(虽然它们不是真正的副本,因为它们每个都有自己唯一的 ID)。

def refresh(self):

    self.session.close_all()
    self.session = CreateSession(self.username, self.password) #custom method defined elsewhere for creating a session

    self.TableViews() #initializing the table views for pyside

    self.WidgetsToAttributes() #connect widgets of the gui to the sqlalchemy scheme attributes

    self.connectSignals() #connects the qt signals to the appropriate functions in code

    pass

(还有一些额外的初始化,但是这里不相关,因为它们只初始化了一些widgets)

上面的函数都是在其他地方用到的,比如GUI的第一次初始化,所以这里不行的是方法的组合。据我所知,造成所有麻烦的是 connectSignals() 方法。信号明显加倍(有时是四倍),单击一次即可输入多个条目(执行代码)。

是什么原因造成的,我该如何避免?

如果您多次调用 connect,您的信号将多次连接到同一个插槽。然后,一个信号将触发对该插槽的多次调用。我认为这就是为什么您在数据库中获得多个条目的原因。

作为一个简单的例子,每次点击按钮时下面的代码都会打印两个“1”:

self.button=QtGui.QPushButton("my button")
self.button.clicked.connect(self.on_click)
self.button.clicked.connect(self.on_click)
def on_click(self):
    print("1")

当对象被销毁时,信号会自动断开。在您的情况下,您销毁 self.session 以创建一个新的。所以每个直接链接到 self.session 的信号都应该被销毁。

但是如果你有这样的事情:

class myWidget(QtGui.QWidget):
    def __init__( self, parent=None):
        super(myWidget, self ).__init__( parent )
        self.button=QtGui.QPushButton("add entry")
        self.button.clicked.connect(self.on_click)

    def on_click(self):
        self.session.add_an_entry()

然后销毁self.session不会断开按钮和on_click函数之间的信号。
所以,你可以不多次调用这种connect,也可以手动删除与disconnect的连接。