基于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
相关产品推荐
相关产品推荐

