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

PyQt单元测试遇TypeError错误及QDialogButtonBox点击模拟问题

问题1 模拟QDialogButtonBox按钮点击的优化方案

你当前直接调用QDialog.accept()的方案可以实现基础需求,如果需要更贴合真实用户操作、覆盖按钮信号绑定逻辑的测试场景,可以通过查找子控件的方式获取QDialogButtonBox实例:

def execute_click(self):
    w = QApplication.activeWindow()
    if isinstance(w, QDialog):
        # 查找Dialog下的QDialogButtonBox子控件
        button_box = w.findChild(QDialogButtonBox)
        if button_box:
            # 获取Ok按钮并触发点击
            ok_btn = button_box.button(QDialogButtonBox.Ok)
            ok_btn.click()

该方案完全模拟用户点击按钮的真实交互流程,测试覆盖度更高。

问题2 TypeError报错原因及解决

报错触发原因是你在程序入口错误调用了unittest模块:unittest(Test().test())。unittest是Python的测试模块,本身不是可调用对象,正确的单元测试入口写法是调用unittest.main(),它会自动加载执行当前文件中的所有测试用例。

修正后的完整可运行代码

import sys
import unittest
import threading
from PyQt5.QtWidgets import (
    QApplication,
    QDialog,
    QDialogButtonBox,
    QGridLayout,
    QGroupBox,
    QLabel,
    QMainWindow,
    QScrollArea,
    QVBoxLayout,
    QWidget,
)

app = QApplication(sys.argv)

class Fortest:
    def dial(self):
        dialog = QDialog()
        buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        layout = QVBoxLayout(dialog)
        param_box = QGroupBox("Iterate over parameters:")
        pblayout = QVBoxLayout()
        pblayout.setContentsMargins(0, 0, 0, 0)
        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setFrameStyle(scroll.NoFrame)
        scroll.setViewportMargins(0, 0, 0, 0)
        pblayout.addWidget(scroll)
        param_lay = QGridLayout()
        wid = QWidget()
        scroll.setWidget(wid)
        wid.setLayout(param_lay)
        param_box.setLayout(pblayout)
        layout.addWidget(param_box)
        layout.addWidget(buttonbox)
        buttonbox.accepted.connect(dialog.accept)
        buttonbox.rejected.connect(dialog.reject)
        param_lay.addWidget(QLabel("iter. / database:"), 0, 0, 1, 3)
        param_lay.addWidget(QLabel("iter.:"), 0, 3, 1, 2)
        param_lay.setColumnStretch(2, 1)
        param_lay.setColumnStretch(4, 1)
        param_lay.setRowStretch(0, 0)
        res = dialog.exec_()
        if res != dialog.Accepted:
            print("dialog not accepted")
            self.a = False
        else:
            print("dialog accepted")
            self.a = True

class Test(unittest.TestCase):
    def test(self):
        b = Fortest()
        threading.Timer(1, self.execute_click).start()
        b.dial()
        self.assertEqual(b.a, True)
    def execute_click(self):
        w = QApplication.activeWindow()
        if isinstance(w, QDialog):
            button_box = w.findChild(QDialogButtonBox)
            if button_box:
                ok_btn = button_box.button(QDialogButtonBox.Ok)
                ok_btn.click()
 

if __name__ == "__main__":
    unittest.main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 12:09:03