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

使用exec()连接多个QPushButton点击信号时程序崩溃问题排查

问题描述

我编写了如下代码:

def top_music_clips(self,clips):
    try:
        self.top_20_clips = clips
        counter = 0
        for clip in self.top_20_clips:
            counter += 1
            exec("self.main_self.ui.music_clip_"+str(counter)+".clicked.connect(lambda state,clip_id="+str(clip["id"])+":self.top_clip_clicked(clip_id))")
            exec("self.main_self.ui.music_clip_"+str(counter)+".setText('"+str(clip["title"])+"')")
            exec("self.main_self.ui.music_clip_"+str(counter)+".setStyleSheet('QPushButton{font-size:7px;}')")
        #example for music_clip_1
        #self.main_self.ui.music_clip_1.clicked.connect(lambda state,clip_id=self.top_20_clips[0]["id"]:self.top_clip_clicked(clip_id))
    except:
        error_message = traceback.format_exc()
        self.main_self.open_music_clip_deck_error_window(error_message)

但点击按钮时程序会崩溃,而注释中直接绑定单个按钮的代码可以正常运行,请问问题出在哪里?

问题原因与解决方案

核心问题:exec字符串拼接导致的变量绑定错误

你用exec拼接lambda表达式时,若clip["id"]是字符串类型,拼接后会丢失引号,导致Python将其识别为未定义的变量,点击按钮时触发变量未定义错误,直接崩溃。

比如clip["id"]为"clip_001",拼接后的lambda代码会变成:

lambda state,clip_id=clip_001:self.top_clip_clicked(clip_id)

这里clip_001会被当作变量名而非字符串,运行时找不到该变量,程序崩溃。

另外,exec的使用完全没必要,既增加调试难度,又容易引入字符串拼接错误。

修复代码

import traceback

def top_music_clips(self, clips):
    try:
        self.top_20_clips = clips
        # 用enumerate直接生成从1开始的计数器,替代手动维护counter
        for counter, clip in enumerate(clips, start=1):
            # 通过getattr直接获取对应按钮控件,避免exec拼接
            btn = getattr(self.main_self.ui, f"music_clip_{counter}")
            # 沿用注释中正确的lambda绑定方式,确保每个按钮绑定当前循环的clip_id
            btn.clicked.connect(lambda state, clip_id=clip["id"]: self.top_clip_clicked(clip_id))
            btn.setText(str(clip["title"]))
            btn.setStyleSheet("QPushButton{font-size:7px;}")
    except:
        error_message = traceback.format_exc()
        self.main_self.open_music_clip_deck_error_window(error_message)

关键优化点

  • 用getattr直接获取UI控件,彻底抛弃exec,避免字符串拼接的各类错误
  • 采用enumerate自动生成计数器,代码更简洁可靠
  • 保留注释中正确的lambda默认参数绑定逻辑,确保每个按钮绑定的是当前循环的clip["id"]值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 08:33:25