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

PyQt5影院管理系统:循环生成按钮点击后无法传递对应影片信息

解决PyQt5循环生成按钮点击仅显示最后一个影片信息的问题

问题原因

循环创建按钮时直接绑定self.openbookingscreen,由于Python闭包的延迟绑定特性,所有按钮的点击事件都会使用循环结束后变量i的最终值(即列表最后一个元素的索引),导致点击任意按钮都显示最后一部影片的信息。

解决方案

下面提供三种可行的解决方法,任选其一即可:

方法1:使用lambda表达式传递当前索引(带默认参数)

修改按钮的clicked信号绑定,通过lambda的默认参数固定当前循环的索引,避免延迟绑定问题:

# 主类中的循环代码修改
for i in range(len(res)):
    if i < 6:
        mov = QPushButton(self.centralwidget)
        mov.setObjectName(f"mov_{i}")
        mov.setGeometry(QtCore.QRect(70 + 307*i, 185, 230, 326))
        mov.setIcon(QIcon(f"{res[i][1]}"))
        mov.setIconSize(QtCore.QSize(260,345))
        mov.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
        mov.raise_()
        # 绑定信号时传递当前索引i,用默认参数固定值
        mov.clicked.connect(lambda checked, idx=i: self.openbookingscreen(idx))

for i in range(6, len(res)):
    mov2 = QPushButton(self.centralwidget)
    mov2.setObjectName(f"mov_{i}")
    mov2.setGeometry(QtCore.QRect(70 + 307*(i-6), 585, 230, 326))
    icon = QPixmap(f"{res[i][1]}")
    scaled = icon.scaled(QtCore.QSize(230, 326))
    mov2.setIcon(QIcon(f"{res[i][1]}"))
    mov2.setIconSize(QtCore.QSize(260, 345))
    mov2.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
    mov2.raise_()
    # 同样传递当前索引i
    mov2.clicked.connect(lambda checked, idx=i: self.openbookingscreen(idx))

# 对应的槽函数修改
def openbookingscreen(self, movie_idx):
    # 根据索引获取对应影片信息
    movie_info = res[movie_idx]
    # 打开预订界面并展示信息(示例逻辑)
    booking_window = BookingScreen()
    booking_window.set_movie_name(movie_info[0])  # 假设res[i][0]是影片名称
    booking_window.show()

方法2:使用functools.partial绑定参数

通过functools.partial将索引参数绑定到槽函数上,直接固定当前循环的索引值:

# 导入functools模块
import functools

# 循环中绑定信号的代码修改
mov.clicked.connect(functools.partial(self.openbookingscreen, i))
# 第二个循环同理
mov2.clicked.connect(functools.partial(self.openbookingscreen, i))

# 槽函数与方法1一致
def openbookingscreen(self, movie_idx):
    movie_info = res[movie_idx]
    # 后续展示逻辑...

方法3:给按钮设置自定义属性

给每个按钮添加自定义属性存储影片索引,在槽函数中通过sender()获取点击的按钮并读取属性:

# 循环中添加属性设置
mov.setProperty("movie_index", i)
mov.clicked.connect(self.openbookingscreen)

# 第二个循环同理
mov2.setProperty("movie_index", i)
mov2.clicked.connect(self.openbookingscreen)

# 槽函数修改
def openbookingscreen(self):
    # 获取点击的按钮
    clicked_btn = self.sender()
    if clicked_btn:
        # 读取自定义属性
        movie_idx = clicked_btn.property("movie_index")
        movie_info = res[movie_idx]
        # 后续展示逻辑...

以上三种方法都能准确识别被点击的按钮,并获取对应影片的信息,解决点击任意按钮都显示最后一部影片的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:31:01