You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QGis 3.x插件信号重复触发问题:如何正确断开信号?

QGIS 3.x插件信号重复触发问题解决方案

问题根源

你当前的代码中,每次调用run()方法都会执行self.dlg.push_button_start.clicked.connect(self.on_pb_start),但对话框实例self.dlg只创建一次,导致信号被重复连接,最终触发槽函数多次。


解决方案一:仅连接一次信号

将信号连接逻辑放在对话框初始化的代码块内,确保只执行一次:

修改my_plugin.py的run()方法:

def run(self):
    """Run method that performs all the real work"""

    # Create the dialog with elements (after translation) and keep reference
    # Only create GUI ONCE in callback, so that it will only load when the plugin is started
    if self.first_start == True:
        self.first_start = False
        self.dlg = MyPluginDialog()
        # 仅在对话框首次创建时连接信号
        self.dlg.push_button_start.clicked.connect(self.on_pb_start)
    # 显示对话框
    self.dlg.show()

解决方案二:先断开再连接(动态场景适用)

如果需要在每次打开对话框时重新绑定信号,可以先尝试断开已有连接(捕获首次无连接的异常),再重新连接:

def run(self):
    """Run method that performs all the real work"""

    if self.first_start == True:
        self.first_start = False
        self.dlg = MyPluginDialog()
    
    try:
        # 尝试断开已有连接
        self.dlg.push_button_start.clicked.disconnect(self.on_pb_start)
    except TypeError:
        # 首次无连接时忽略异常
        pass
    # 重新连接信号
    self.dlg.push_button_start.clicked.connect(self.on_pb_start)
    # 显示对话框
    self.dlg.show()

在initGui()中访问对话框对象的方法

可以在initGui()阶段提前初始化对话框实例,这样就能直接访问UI元素:

修改my_plugin.py的initGui()和run():

def initGui(self):
    """Create the menu entries and toolbar icons inside the QGIS GUI."""

    icon_path = ':/plugins/my_plugin/icon.png'
    self.add_action(
        icon_path,
        text=self.tr(u'Start My Plugin'),
        callback=self.run,
        parent=self.iface.mainWindow())

    # 提前初始化对话框
    self.dlg = MyPluginDialog()
    # 直接在这里连接信号或访问UI元素
    self.dlg.push_button_start.clicked.connect(self.on_pb_start)

def run(self):
    """Run method that performs all the real work"""
    # 直接显示对话框
    self.dlg.show()

插件关闭时自动断开所有信号

在unload()方法中销毁对话框实例,Qt会自动处理所有信号的断开:

def unload(self):
    """Removes the plugin menu item and icon from QGIS GUI."""
    self.remove_action(self.action)
    
    # 销毁对话框,自动断开所有信号
    if hasattr(self, 'dlg'):
        self.dlg.close()
        self.dlg.deleteLater()
        del self.dlg

内容的提问来源于stack exchange,提问作者Beinje

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:39:19