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

动态向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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:40:42