PySide6.5.1循环创建Widget属性异常,点击均返回初始值求助
问题描述
使用PySide6 6.5.1版本时,在主窗口循环创建的按钮均被赋予对应行列的objectName,但点击所有按钮都打印row=0, col=0,其他Widget属性也存在同样异常;而在6.4.2版本中该功能正常。相关代码如下:
from PySide6.QtWidgets import QPushButton, QWidget, QMainWindow, QGridLayout, QApplication class CustomButton(QPushButton): def __init__(self, parent: QWidget, row: int, col: int, slot: Callable): super().__init__(parent=parent) self.setObjectName(f'{row=}, {col=}') self.setText(f'{row=}, {col=}') self.released.connect(lambda: slot(self)) class MainWindow(QMainWindow): def __init__(self, parent: QApplication): super().__init__() self.central_widget = QWidget() self.setCentralWidget(self.central_widget) self.layout = QGridLayout(self.central_widget) self.create_buttons() def create_buttons(self): for r in range(10): for c in range(10): button = CustomButton(self, r, c, self.button_clicked) self.layout.addWidget(button, r, c) def button_clicked(self, button: QPushButton): print(button.objectName()) if __name__ == '__main__': app = QApplication() window = MainWindow(app) window.show() app.exec()
原因分析
问题根源在于错误地将QApplication实例作为QMainWindow的父控件传递:
- Qt规定QWidget的父控件必须是另一个QWidget实例或
None,QApplication是应用程序级对象,不属于QWidget子类,不能作为控件的父对象。 - PySide6 6.4.2版本对该不合规操作未触发异常,但6.5.1版本的内部逻辑优化后,这种错误的父对象设置干扰了子控件(CustomButton)的属性初始化与绑定流程,导致所有按钮的属性最终被错误覆盖为初始循环值
row=0, col=0。
修复方案
- 调整MainWindow的构造函数,修正父参数的类型与传递逻辑;
- 优化按钮的父控件指向,将其设置为central_widget而非主窗口,更符合Qt布局规范。
修复后的完整代码:
from typing import Callable, Optional from PySide6.QtWidgets import QPushButton, QWidget, QMainWindow, QGridLayout, QApplication class CustomButton(QPushButton): def __init__(self, parent: QWidget, row: int, col: int, slot: Callable): super().__init__(parent=parent) self.setObjectName(f'{row=}, {col=}') self.setText(f'{row=}, {col=}') self.released.connect(lambda: slot(self)) class MainWindow(QMainWindow): def __init__(self, parent: Optional[QWidget] = None): super().__init__(parent=parent) self.central_widget = QWidget() self.setCentralWidget(self.central_widget) self.layout = QGridLayout(self.central_widget) self.create_buttons() def create_buttons(self): for r in range(10): for c in range(10): # 将按钮父控件改为central_widget button = CustomButton(self.central_widget, r, c, self.button_clicked) self.layout.addWidget(button, r, c) def button_clicked(self, button: QPushButton): print(button.objectName()) if __name__ == '__main__': app = QApplication() window = MainWindow() # 无需传递QApplication作为父控件 window.show() app.exec()
内容的提问来源于stack exchange,提问作者Thomas Ruff
相关产品推荐
相关产品推荐

