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

基于JSON的PySide6按钮生成器问题:点击仅更新最后一个JSON项

问题描述
  • 需求:基于JSON数据生成每行最多4个按钮的PySide6 UI组件,替代手动编写重复代码,适配任意JSON模板。
  • 问题:点击不同图标按钮时,全局变量controllers['current_products']只会添加JSON中最后一个产品项的计数,而非对应按钮的产品项,期望每个按钮点击时更新对应产品的计数。
问题原因

循环创建按钮时,所有按钮的点击事件都绑定到了self.templates方法,但self.texti是实例变量,循环结束后它的值会被最后一个产品的名称覆盖。当按钮触发点击事件时,templates方法读取的是最后一次赋值的self.texti,导致所有按钮都会更新同一个产品的计数。

解决方案

为每个按钮绑定独立的产品信息,避免共享变量的覆盖问题。推荐使用lambda函数传递当前产品参数,同时优化布局逻辑确保每行最多4个按钮,并完善计数更新逻辑。

修改后的完整代码
import os
import sys
import json
import datetime
from PySide6.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QVBoxLayout
from PySide6.QtGui import QIcon
from PySide6.QtCore import QSize, Qt

location = f"./{str(datetime.datetime.now().strftime('%Y%m%d'))}.json"

class MainWindow(QWidget): 
    def __init__(self):
        super().__init__()
        self.wrappers = QVBoxLayout()
        self.setWindowTitle("产品选择界面")

        with open('./bin/properties.json') as file:
            self.json_content = json.load(file)

        # 遍历每个section
        for section_name, products in self.json_content.items():
            # 添加section标题
            section_label = QLabel(section_name)
            section_label.setStyleSheet("font-size: 16px; font-weight: bold;")
            self.wrappers.addWidget(section_label)

            # 按每行4个产品分组
            product_groups = [products[i:i+4] for i in range(0, len(products), 4)]
            
            # 创建每组的水平布局
            for group in product_groups:
                product_layout = QHBoxLayout()
                product_layout.setAlignment(Qt.AlignmentFlag.AlignLeft)
                product_layout.setSpacing(20)  # 设置按钮间距

                for product in group:
                    btn_layout = QVBoxLayout()
                    btn_layout.setAlignment(Qt.AlignmentFlag.AlignCenter)

                    # 创建按钮
                    btn = QPushButton()
                    btn.setFixedSize(100, 100)
                    btn.setIcon(QIcon(product['icons']))
                    btn.setIconSize(QSize(110, 110))
                    # 使用lambda传递当前产品信息,避免变量捕获问题
                    btn.clicked.connect(lambda checked, p=product: self.update_product_count(p))

                    # 创建计数标签
                    count_label = QLabel("0")
                    count_label.setStyleSheet("font-size: 14px;")

                    btn_layout.addWidget(btn)
                    btn_layout.addWidget(count_label)
                    product_layout.addLayout(btn_layout)

                self.wrappers.addLayout(product_layout)
        
        self.setLayout(self.wrappers)
        self.resize(800, 600)  # 设置窗口初始大小

    def update_product_count(self, product):
        product_name = product['products']
        # 更新产品计数
        if product_name in controllers['current_products']:
            controllers['current_products'][product_name] += 1
        else:
            controllers['current_products'][product_name] = 1
        # 更新总价格
        controllers['current_prices'] += product['prices']
        # 打印调试信息
        print(f"当前产品计数: {controllers['current_products']}")
        print(f"当前总价格: {controllers['current_prices']}")

def global_var():
    global controllers
    controllers = {
        'current_products': {}, 
        'current_prices': 0, 
        'customer_moneys': 0, 
        'current_expenses': 0, 
        'current_reasons': ''
    }

if __name__ == "__main__":
    if not os.path.isfile(location):
        with open(location, 'w') as f:
            json.dump({}, f)
    os.chdir(os.path.dirname(sys.argv[0]))
    global_var()

    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    app.exec()
JSON配置文件示例
{
    "section":
    [
        {
            "products": "产品A",
            "categories": "分类1",
            "icons": "img/section1/product1.jpg",
            "prices": 10
        },
        {
            "products": "产品B",
            "categories": "分类1",
            "icons": "img/section1/product2.jpg",
            "prices": 20
        },
        {
            "products": "产品C",
            "categories": "分类1",
            "icons": "img/section1/product3.jpg",
            "prices": 15
        },
        {
            "products": "产品D",
            "categories": "分类1",
            "icons": "img/section1/product4.jpg",
            "prices": 25
        },
        {
            "products": "产品E",
            "categories": "分类1",
            "icons": "img/section1/product5.jpg",
            "prices": 30
        }
    ],
    "section2":
    [
        {
            "products": "产品X",
            "categories": "分类2",
            "icons": "img/section2/product1.jpg",
            "prices": 5
        },
        {
            "products": "产品Y",
            "categories": "分类2",
            "icons": "img/section2/product2.jpg",
            "prices": 8
        }
    ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:02:11