动态向QStackedWidget添加QTreeWidget为何会重置字体样式?
QStackedWidget动态添加页面样式失效问题解决
你的场景是:使用QStackedWidget,第一页嵌入自定义组件widget_1.py时字体样式正常,点击按钮动态添加第二页(复用同一组件)后,页面中QTreeWidget的子项字体变为默认样式,其余功能正常。

堆叠组件第一页,字体样式正常

堆叠组件第二页,字体样式为默认
问题根源
你的自定义Widget初始化方式不符合Qt的设计逻辑:将widget_1_UI设计为QWidget子类后,却在外部手动调用setupUi传入Widget实例本身。这种写法会导致:
- 第一页在Dialog初始化阶段创建(未显示),Qt样式传播机制能正常工作,TreeWidget子项自动继承父控件字体
- 第二页在Dialog显示后动态创建,手动调用
setupUi的方式破坏了样式传播流程,TreeWidget子项无法正确继承字体样式
解决方案
修改widget_1.py,将setupUi的调用整合到Widget的__init__方法中,让实例化时自动完成初始化:
修改后的widget_1.py
from PyQt5 import QtCore, QtGui, QtWidgets class widget_1_UI(QtWidgets.QWidget): def __init__(self, parent=None): super().__init__(parent) # 初始化时自动调用setupUi,传入当前Widget实例 self.setupUi(self) def setupUi(self, Form): Form.resize(614, 411) Form.setWindowTitle("Main Dialog") self.verticalLayout = QtWidgets.QVBoxLayout(Form) self.label = QtWidgets.QLabel(Form) font = QtGui.QFont() font.setFamily("Arial Narrow") font.setPointSize(16) font.setBold(True) font.setWeight(75) self.label.setFont(font) self.label.setText("Cat Type") self.verticalLayout.addWidget(self.label) self.treeWidget = QtWidgets.QTreeWidget(Form) font = QtGui.QFont() font.setFamily("Arial Narrow") font.setPointSize(12) self.treeWidget.setFont(font) self.treeWidget.header().setVisible(False) self.catTypes = ["Happy", "Sleepy", "Hangry", "Needy", "Kneedy"] self.catSubtype = ["Orange", "Black", "Brown", "White"] for index in range(len(self.catTypes)): item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) item_0.setText(0, self.catTypes[index]) for count in range(len(self.catSubtype)): item_1 = QtWidgets.QTreeWidgetItem(item_0) item_1.setText(0, self.catSubtype[count]) self.verticalLayout.addWidget(self.treeWidget)
同步修改dialog.py
去掉手动调用setupUi的冗余代码:
from PyQt5 import QtCore, QtGui, QtWidgets from widget_1 import widget_1_UI class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.resize(640, 480) Dialog.setWindowTitle("I'm a cat. I'm a kitty cat.") self.addPage2 = False self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) self.stackedWidget = QtWidgets.QStackedWidget(Dialog) # 实例化后自动完成初始化,无需手动调用setupUi self.page_1 = widget_1_UI() self.stackedWidget.insertWidget(0, self.page_1) self.stackedWidget.setCurrentIndex(0) self.verticalLayout.addWidget(self.stackedWidget) self.btn_nextPage = QtWidgets.QPushButton(Dialog) self.btn_nextPage.setText("Switch Page") self.verticalLayout.addWidget(self.btn_nextPage) self.btn_nextPage.clicked.connect(self.addSecond) self.btn_nextPage.clicked.connect(self.nextPage) def nextPage(self): num = self.stackedWidget.currentIndex() if num == 0: self.stackedWidget.setCurrentIndex(1) else: self.stackedWidget.setCurrentIndex(0) def addSecond(self): if not self.addPage2: # 同样无需手动调用setupUi self.page_2 = widget_1_UI() self.stackedWidget.insertWidget(1, self.page_2) self.addPage2 = True if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) Dialog = QtWidgets.QDialog() ui = Ui_Dialog() ui.setupUi(Dialog) Dialog.show() sys.exit(app.exec_())
备选临时方案(不推荐)
如果暂时无法修改Widget结构,也可以在创建TreeWidget子项时显式设置字体:
# 在widget_1.py的setupUi方法中,创建item时添加字体设置 item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget) item_0.setFont(0, self.treeWidget.font()) # 显式继承父控件字体 item_0.setText(0, self.catTypes[index]) for count in range(len(self.catSubtype)): item_1 = QtWidgets.QTreeWidgetItem(item_0) item_1.setFont(0, self.treeWidget.font()) # 显式继承父控件字体 item_1.setText(0, self.catSubtype[count])
这种方法仅能临时解决样式问题,推荐使用第一种修改方式,遵循Qt自定义Widget的标准设计逻辑。
内容的提问来源于stack exchange,提问作者ARChalifour
相关产品推荐
相关产品推荐

