Why is PyQt executing my actions three times?

こ雲淡風輕ζ 提交于 2019-12-03 15:49:20

If you scroll down to the bottom of the setupUi method in the ui module, you'll see this line:

    QtCore.QMetaObject.connectSlotsByName(RSLEditorClass)

What this does, is to automatically connect signals to slots based on the format of the slot names. The format of the slot name is:

    on_[object name]_[signal name]

So looking at the way you're connecting your actions:

    self.ui.actionNew.triggered.connect(self.on_actionNew_triggered)

it should be clear that you're using this format when naming your slots, and that that is where the problem lies. But why does this cause the slot to be called three times? Well, in PyQt, the triggered signal has two overloads: one which sends the default checked parameter, and one which doesn't. If you don't specify which one of these you want to connect to, both overloads will get connected. So in your case, what happens is that on_actionNew_triggered gets connected twice by connectSlotsByName and once by your own explicit connection, making three in all. And presumably, a similar story can be told for the other actions.

To fix this, you can either rename your slots so they don't use the auto-connection format:

    self.ui.actionNew.triggered.connect(self.handleActionNew)
    ...

    def handleActionNew(self):
    ...

or get rid of the explicit connection, and use the pyqtSlot decorator to select the right overload for auto-connection:

    @QtCore.pyqtSlot()
    def on_actionNew_triggered(self):
    ...

or:

    @QtCore.pyqtSlot(bool)
    def on_actionNew_triggered(self, checked):
    ...
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!