149 lines
5.0 KiB
Python
149 lines
5.0 KiB
Python
|
|
"""
|
|||
|
|
测试配置对话框崩溃修复
|
|||
|
|
|
|||
|
|
测试场景:
|
|||
|
|
1. 频繁打开配置对话框
|
|||
|
|
2. 不选择类型就关闭
|
|||
|
|
3. 反复操作,检查是否崩溃
|
|||
|
|
|
|||
|
|
修复内容:
|
|||
|
|
1. _run_in_background_silent 使用 QueuedConnection 确保回调在主线程执行
|
|||
|
|
2. _on_alarm_tick 降低 pymodbus 日志级别,避免连接失败时的噪音
|
|||
|
|
3. 配置对话框使用 deleteLater() 确保资源正确释放
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import sys
|
|||
|
|
from pathlib import Path
|
|||
|
|
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
|
|||
|
|
from PySide6.QtCore import QTimer
|
|||
|
|
|
|||
|
|
# 添加项目路径
|
|||
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|||
|
|
|
|||
|
|
from config_type_selector import select_config_for_settings
|
|||
|
|
|
|||
|
|
|
|||
|
|
class TestWindow(QMainWindow):
|
|||
|
|
def __init__(self):
|
|||
|
|
super().__init__()
|
|||
|
|
self.setWindowTitle("测试配置对话框崩溃修复")
|
|||
|
|
self.resize(400, 300)
|
|||
|
|
|
|||
|
|
# 计数器
|
|||
|
|
self.open_count = 0
|
|||
|
|
self.close_count = 0
|
|||
|
|
|
|||
|
|
# 创建UI
|
|||
|
|
central = QWidget()
|
|||
|
|
layout = QVBoxLayout()
|
|||
|
|
|
|||
|
|
# 手动测试按钮
|
|||
|
|
manual_btn = QPushButton("手动测试:打开配置对话框")
|
|||
|
|
manual_btn.clicked.connect(self.open_dialog_manual)
|
|||
|
|
layout.addWidget(manual_btn)
|
|||
|
|
|
|||
|
|
# 自动测试按钮
|
|||
|
|
auto_btn = QPushButton("自动测试:连续打开/关闭 20 次")
|
|||
|
|
auto_btn.clicked.connect(self.start_auto_test)
|
|||
|
|
layout.addWidget(auto_btn)
|
|||
|
|
|
|||
|
|
# 状态标签
|
|||
|
|
from PySide6.QtWidgets import QLabel
|
|||
|
|
self.status_label = QLabel("等待测试...")
|
|||
|
|
layout.addWidget(self.status_label)
|
|||
|
|
|
|||
|
|
central.setLayout(layout)
|
|||
|
|
self.setCentralWidget(central)
|
|||
|
|
|
|||
|
|
# 自动测试定时器
|
|||
|
|
self.auto_timer = QTimer()
|
|||
|
|
self.auto_timer.timeout.connect(self.auto_test_step)
|
|||
|
|
self.auto_test_count = 0
|
|||
|
|
self.auto_test_max = 20
|
|||
|
|
|
|||
|
|
def open_dialog_manual(self):
|
|||
|
|
"""手动打开对话框"""
|
|||
|
|
self.open_count += 1
|
|||
|
|
print(f"\n{'='*60}")
|
|||
|
|
print(f"[测试] 第 {self.open_count} 次打开对话框")
|
|||
|
|
print(f"{'='*60}")
|
|||
|
|
|
|||
|
|
category = select_config_for_settings(self)
|
|||
|
|
|
|||
|
|
if category:
|
|||
|
|
print(f"[测试] 用户选择: {category.name}")
|
|||
|
|
self.status_label.setText(f"选择了: {category.name} (共打开 {self.open_count} 次)")
|
|||
|
|
else:
|
|||
|
|
self.close_count += 1
|
|||
|
|
print(f"[测试] 用户取消 (第 {self.close_count} 次取消)")
|
|||
|
|
self.status_label.setText(f"取消 (共打开 {self.open_count} 次,取消 {self.close_count} 次)")
|
|||
|
|
|
|||
|
|
def start_auto_test(self):
|
|||
|
|
"""开始自动测试"""
|
|||
|
|
self.auto_test_count = 0
|
|||
|
|
self.open_count = 0
|
|||
|
|
self.close_count = 0
|
|||
|
|
print(f"\n{'='*60}")
|
|||
|
|
print(f"[自动测试] 开始连续打开/关闭对话框 {self.auto_test_max} 次")
|
|||
|
|
print(f"{'='*60}")
|
|||
|
|
self.status_label.setText(f"自动测试中: 0/{self.auto_test_max}")
|
|||
|
|
self.auto_timer.start(500) # 每 500ms 打开一次
|
|||
|
|
|
|||
|
|
def auto_test_step(self):
|
|||
|
|
"""自动测试步骤"""
|
|||
|
|
if self.auto_test_count >= self.auto_test_max:
|
|||
|
|
self.auto_timer.stop()
|
|||
|
|
print(f"\n{'='*60}")
|
|||
|
|
print(f"[自动测试] 完成!共打开 {self.open_count} 次,取消 {self.close_count} 次")
|
|||
|
|
print(f"{'='*60}")
|
|||
|
|
self.status_label.setText(f"自动测试完成: {self.auto_test_max}/{self.auto_test_max} ✓")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
self.auto_test_count += 1
|
|||
|
|
self.open_count += 1
|
|||
|
|
|
|||
|
|
print(f"[自动测试] 第 {self.auto_test_count}/{self.auto_test_max} 次")
|
|||
|
|
|
|||
|
|
# 创建对话框但立即关闭(模拟用户不选择就关闭)
|
|||
|
|
from config_type_selector import ConfigTypeSelectorDialog
|
|||
|
|
dialog = ConfigTypeSelectorDialog(self, "测试", "自动测试中...")
|
|||
|
|
|
|||
|
|
# 使用 QTimer 延迟关闭,模拟用户操作
|
|||
|
|
QTimer.singleShot(100, dialog.reject)
|
|||
|
|
|
|||
|
|
result = dialog.exec()
|
|||
|
|
|
|||
|
|
if result:
|
|||
|
|
print(f"[自动测试] 意外:对话框被接受")
|
|||
|
|
else:
|
|||
|
|
self.close_count += 1
|
|||
|
|
print(f"[自动测试] 对话框已关闭")
|
|||
|
|
|
|||
|
|
self.status_label.setText(f"自动测试中: {self.auto_test_count}/{self.auto_test_max}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
app = QApplication(sys.argv)
|
|||
|
|
|
|||
|
|
print("="*60)
|
|||
|
|
print("配置对话框崩溃修复测试")
|
|||
|
|
print("="*60)
|
|||
|
|
print("\n测试说明:")
|
|||
|
|
print("1. 点击'手动测试'按钮,打开配置对话框,然后点击取消")
|
|||
|
|
print("2. 重复多次,观察是否崩溃")
|
|||
|
|
print("3. 或点击'自动测试'按钮,自动连续打开/关闭 20 次")
|
|||
|
|
print("\n修复内容:")
|
|||
|
|
print("- _run_in_background_silent 使用 QueuedConnection")
|
|||
|
|
print("- _on_alarm_tick 降低 pymodbus 日志级别")
|
|||
|
|
print("- 配置对话框使用 deleteLater() 释放资源")
|
|||
|
|
print("="*60)
|
|||
|
|
|
|||
|
|
window = TestWindow()
|
|||
|
|
window.show()
|
|||
|
|
|
|||
|
|
sys.exit(app.exec())
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|