(定时器,绘制事件,qt简单服务器的搭建)2025.2.11

作业

笔记(复习补充)

1> 制作一个闹钟软件

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>      //按钮类
#include <QTimer>           //定时器类
#include <QTime>            //时间类
#include <QLineEdit>        //单行文本输入框类
#include <QLabel>           //标签类
#include <QVBoxLayout>      //垂直布局类
#include <QHBoxLayout>      //水平布局类
#include <QDateTime>   // 包含QDateTime类,用于处理日期和时间
#include <QMessageBox> // 包含QMessageBox类,用于显示消息框

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:  //槽函数声明
    void updateTime();  // 更新显示的系统时间
    void startAlarm();  // 启动闹钟功能
    void cancelAlarm();  // 取消已设置的闹钟
private:
    Ui::Widget *ui;

    //声明指针变量等
    QLabel *Mylabel;    //标签对象指针,用于显示时间
    QLineEdit *Myline;  //单行输入框对象,用于输入闹钟时间

    QPushButton *Mybtn1; //按钮对象,用于启动闹钟(这两也可以只用一个)
    QPushButton *Mybtn2; //按钮对象,用于关闭闹钟

    QTimer *Mytimer;       //定时器对象,用于更新系统时间
    QTimer *mytimer1;      //定时器对象,用于触发对象
    bool myset;             //用于标记闹钟是否已经设置

    QVBoxLayout *MymainLayout;
    QHBoxLayout *MybuttonLayout;
};
#endif // WIDGET_H

源文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //认父类,实例化
    this->Mytimer = new QTimer(this);
    this->mytimer1 = new QTimer(this);
    this->myset = false;

    //创建用户界面控件
    Mylabel = new QLabel("00:00:00",this);  //创建显示时间的标签
    Myline = new QLineEdit("00:00:00",this);//创建输入时间的文本
    Mybtn1 = new QPushButton("启动",this);    //创建启动闹钟的按钮
    Mybtn2 = new QPushButton("取消",this);    //创建取消闹钟的按钮

    // 设置布局管理器
        MymainLayout = new QVBoxLayout;  // 创建垂直布局管理器
        MybuttonLayout = new QHBoxLayout;  // 创建水平布局管理器

        MybuttonLayout->addWidget(Mybtn1);  // 将启动按钮添加到水平布局
        MybuttonLayout->addWidget(Mybtn2);  // 将取消按钮添加到水平布局

        MymainLayout->addWidget(Mylabel);  // 将时间标签添加到垂直布局
        MymainLayout->addWidget(Myline);  // 将时间输入框添加到垂直布局
        MymainLayout->addLayout(MybuttonLayout);  // 将水平布局添加到垂直布局
        // 设置主窗口的布局
           this->setLayout(MymainLayout);  // 将垂直布局设置为主窗口的布局

           // 连接信号和槽
           connect(Mytimer, &QTimer::timeout, this, &Widget::updateTime);  // 连接定时器信号到更新时间槽函数
           connect(Mybtn1, &QPushButton::clicked, this,&Widget::startAlarm);  // 连接启动按钮信号到启动闹钟槽函数
           connect(Mybtn2, &QPushButton::clicked, this,&Widget::cancelAlarm);  // 连接取消按钮信号到取消闹钟槽函数
           // 启动定时器
            Mytimer->start(1000);  // 设置定时器间隔为1秒
 }

Widget::~Widget()
{
    delete ui;
}

void Widget::updateTime()
{
    // 更新时间标签显示当前系统时间
       Mylabel->setText(QDateTime::currentDateTime().toString("hh:mm:ss"));
}

void Widget::startAlarm()
{
    // 获取用户输入的时间并启动闹钟
        QString inputTime = Myline->text();  // 获取输入框中的时间
        if (!inputTime.isEmpty()) {
            QTime targetTime = QTime::fromString(inputTime, "hh:mm:ss");  // 将输入的时间字符串转换为QTime对象
            QDateTime currentTime = QDateTime::currentDateTime();  // 获取当前时间
            QDateTime targetDateTime = currentTime.addSecs(targetTime.msecsTo(currentTime.time()));  // 计算目标时间

            mytimer1->stop();  // 停止之前的定时器(如果有)
            mytimer1->setInterval(targetDateTime.msecsTo(QDateTime::currentDateTime()));  // 设置定时器间隔
            connect(mytimer1, &QTimer::timeout, this, [&]() {  // 连接定时器信号到槽函数
                QMessageBox::information(this, "Alarm", "Time's up!");  // 弹出闹钟提醒
                myset = false;  // 重置闹钟设置标记
                mytimer1->stop();  // 停止定时器
            });
            mytimer1->start();  // 启动定时器
            myset = true;  // 设置闹钟设置标记为已设置
        } else {
            QMessageBox::warning(this, "Warning", "Please set a valid time.");  // 提示用户输入有效时间
        }
}



void Widget::cancelAlarm()
{
    // 取消已设置的闹钟
       if (myset) {
           Mytimer->stop();  // 停止定时器
           myset = false;  // 重置闹钟设置标记
           QMessageBox::information(this, "Alarm Canceled", "Alarm has been canceled.");  // 提示用户闹钟已取消
       }
}

2> 使用绘制实现,实现时钟(君子作业)

3> 将网络聊天室服务器端,重新实现一遍

4> 思维导图

5> 牛客网上 两个 28

#下面程序运行时报错: "C:\Program Files\Python312\python.exe" C:\Users\Administrator\py2025\GPS对抗程序A.py Traceback (most recent call last): File "C:\Users\Administrator\py2025\GPS对抗程序A.py", line 863, in <module> window = GPSJammingSimulator() ^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\py2025\GPS对抗程序A.py", line 210, in __init__ control_panel = self.create_control_panel() ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\py2025\GPS对抗程序A.py", line 307, in create_control_panel self.sat_id_spin = QSpinBox() ^^^^^^^^ NameError: name 'QSpinBox' is not defined 进程已结束,退出代码为 1 ============================= import sys import numpy as np from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, QGroupBox, QLabel, QSlider, QComboBox, QPushButton, QDoubleSpinBox, QCheckBox, QFrame) from PyQt5.QtCore import Qt, QTimer from PyQt5.QtGui import QFont, QPalette, QColor import matplotlib.pyplot as plt from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure # 添加中文字体支持 plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'SimSun', 'Arial Unicode MS'] # 设置中文字体 plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题 class GPSSystem: def __init__(self): # GPS信号参数(L1频段) self.satellite_id = 1 # 卫星编号 self.carrier_freq = 1575.42 # L1频段中心频率(MHz) self.signal_power = -160 # dBW self.code_rate = 1.023 # C/A码速率(Mcps) self.data_rate = 50 # 导航数据速率(bps) self.modulation_type = "BPSK" # 调制方式 # 环境参数 self.iono_delay = 5 # 电离层延迟(ns) self.tropo_delay = 1.5 # 对流层延迟(ns) self.multipath = 0.5 # 多径效应幅度 # 干扰参数 self.jamming_type = "None" # None, Narrowband, Pulse, Spoofing, Swept self.jamming_power = -100 # dBW self.jamming_freq = 1575.42 # 干扰频率(MHz) self.spoofing_delay = 0.1 # 欺骗干扰延迟(ms) self.spoofing_count = 1 # 虚假卫星数量 # 系统参数 self.sample_rate = 100 # 采样率(MS/s) self.duration = 1 # 信号持续时间(ms) self.noise_power = -200 # 热噪声功率(dBW) # 卫星信息 self.satellite_pos = np.array([12000, 20000, 5000]) # 卫星位置(km) self.user_pos = np.array([0, 0, 0]) # 用户位置(km) def generate_gps_signal(self): """生成GPS信号""" t = np.linspace(0, self.duration, int(self.sample_rate * self.duration * 1e3)) # 计算传播时延 distance = np.linalg.norm(self.satellite_pos - self.user_pos) propagation_delay = distance / 3e5 # 光速(km/ms) # 生成C/A码(简化模拟) ca_code = np.random.choice([-1, 1], size=len(t)) # 生成导航数据 data_bits = np.random.choice([-1, 1], size=int(self.data_rate * self.duration * 1e-3)) data_signal = np.repeat(data_bits, len(t) // len(data_bits)) # 构建BPSK信号 if self.modulation_type == "BPSK": phase = 2 * np.pi * self.carrier_freq * t * 1e6 * 1e-3 # 转换为Hz和秒 signal = 10 ** (self.signal_power / 20) * (ca_code * data_signal) * np.sin(phase) else: signal = np.zeros_like(t) return t, signal def generate_interference(self, t): """生成干扰信号""" if self.jamming_type == "None": return np.zeros_like(t) elif self.jamming_type == "Narrowband": # 窄带干扰 phase = 2 * np.pi * self.jamming_freq * t * 1e6 * 1e-3 return 10 ** (self.jamming_power / 20) * np.sin(phase) elif self.jamming_type == "Pulse": # 脉冲干扰 pulse_width = 0.1 # 脉冲宽度(ms) pulse_start = np.random.uniform(0, self.duration - pulse_width) pulse = np.zeros_like(t) pulse[(t >= pulse_start) & (t <= pulse_start + pulse_width)] = 1 phase = 2 * np.pi * self.jamming_freq * t * 1e6 * 1e-3 return 10 ** (self.jamming_power / 20) * pulse * np.sin(phase) elif self.jamming_type == "Swept": # 扫频干扰 sweep_rate = 10 # 扫频速率(MHz/ms) freq = self.jamming_freq + sweep_rate * t phase = 2 * np.pi * freq * t * 1e6 * 1e-3 return 10 ** (self.jamming_power / 20) * np.sin(phase) elif self.jamming_type == "Spoofing": # 欺骗干扰 spoofing_signal = np.zeros_like(t) for i in range(self.spoofing_count): delay = self.spoofing_delay * (i + 1) phase = 2 * np.pi * self.carrier_freq * (t - delay) * 1e6 * 1e-3 spoofing_signal += 10 ** ((self.jamming_power - 3) / 20) * np.sin(phase) return spoofing_signal return np.zeros_like(t) def add_noise(self, signal): """添加热噪声""" noise_power_linear = 10 ** (self.noise_power / 10) noise = np.random.normal(0, np.sqrt(noise_power_linear / 2), len(signal)) * 1j noise += np.random.normal(0, np.sqrt(noise_power_linear / 2), len(signal)) return signal + noise.real def add_multipath(self, signal): """添加多径效应""" if self.multipath > 0: delay_samples = int(0.1 * self.sample_rate * 1e3 * self.duration / 1000) multipath_signal = np.roll(signal, delay_samples) multipath_signal[:delay_samples] = 0 return signal + self.multipath * multipath_signal return signal def calculate_pseudorange(self, signal): """计算伪距""" # 简化的伪距计算 noise_signal = self.add_noise(signal) interference_signal = self.generate_interference(t) combined_signal = noise_signal + interference_signal # 简单的信号检测 correlation = np.abs(np.correlate(combined_signal, signal[:100], mode='valid')) peak_index = np.argmax(correlation) # 计算伪距 pseudorange = (peak_index / (self.sample_rate * 1e6)) * 3e8 / 1e3 # km pseudorange += self.iono_delay * 0.3 # 电离层修正 pseudorange += self.tropo_delay * 0.1 # 对流层修正 return pseudorange def calculate_position(self): """计算位置""" # 简单的多卫星位置计算 true_position = self.user_pos estimated_position = np.zeros(3) # 模拟多个卫星观测 for _ in range(4): # 至少需要4颗卫星 self.satellite_pos = np.random.uniform(10000, 20000, 3) pseudorange = self.calculate_pseudorange(self.generate_gps_signal()[1]) estimated_position += (self.satellite_pos - (pseudorange / np.linalg.norm(self.satellite_pos)) * (self.satellite_pos - true_position)) return estimated_position / 4 def calculate_dop(self): """计算几何精度因子""" # 简化的DOP计算 satellite_positions = np.random.uniform(10000, 20000, (8, 3)) geometry_matrix = np.zeros((8, 4)) for i, sat_pos in enumerate(satellite_positions): sat_dist = np.linalg.norm(sat_pos) geometry_matrix[i, :3] = sat_pos / sat_dist geometry_matrix[i, 3] = 1 try: q_matrix = np.linalg.inv(geometry_matrix.T @ geometry_matrix) pdop = np.sqrt(q_matrix[0, 0] + q_matrix[1, 1] + q_matrix[2, 2]) hdop = np.sqrt(q_matrix[0, 0] + q_matrix[1, 1]) vdop = np.sqrt(q_matrix[2, 2]) except np.linalg.LinAlgError: pdop, hdop, vdop = 99.9, 99.9, 99.9 return pdop, hdop, vdop class GPSJammingSimulator(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("GPS对抗仿真系统") self.setGeometry(100, 50, 1400, 900) # 初始化GPS系统 self.gps_system = GPSSystem() # 设置深色主题 self.set_dark_theme() # 创建主控件 self.main_widget = QWidget() self.setCentralWidget(self.main_widget) # 主布局 main_layout = QVBoxLayout(self.main_widget) main_layout.setSpacing(15) main_layout.setContentsMargins(20, 20, 20, 20) # 标题 title_label = QLabel("GPS对抗仿真系统") title_label.setFont(QFont("Arial", 24, QFont.Bold)) title_label.setStyleSheet("color: #1E90FF;") title_label.setAlignment(Qt.AlignCenter) main_layout.addWidget(title_label) # 创建控制面板 control_panel = self.create_control_panel() main_layout.addWidget(control_panel) # 创建信号显示区域 signal_panel = self.create_signal_panel() main_layout.addWidget(signal_panel, 1) # 创建位置显示区域 position_panel = self.create_position_panel() main_layout.addWidget(position_panel) # 创建状态显示区域 status_panel = self.create_status_panel() main_layout.addWidget(status_panel) # 初始化数据 self.update_simulation() # 设置定时器用于实时更新 self.timer = QTimer(self) self.timer.timeout.connect(self.update_simulation) self.timer.start(100) # 每100ms更新一次 def set_dark_theme(self): """设置深色主题""" dark_palette = QPalette() dark_palette.setColor(QPalette.Window, QColor(25, 35, 45)) dark_palette.setColor(QPalette.WindowText, Qt.white) dark_palette.setColor(QPalette.Base, QColor(35, 45, 55)) dark_palette.setColor(QPalette.AlternateBase, QColor(45, 55, 65)) dark_palette.setColor(QPalette.ToolTipBase, Qt.white) dark_palette.setColor(QPalette.ToolTipText, Qt.white) dark_palette.setColor(QPalette.Text, Qt.white) dark_palette.setColor(QPalette.Button, QColor(50, 65, 80)) dark_palette.setColor(QPalette.ButtonText, Qt.white) dark_palette.setColor(QPalette.BrightText, Qt.red) dark_palette.setColor(QPalette.Highlight, QColor(30, 144, 255)) dark_palette.setColor(QPalette.HighlightedText, Qt.black) self.setPalette(dark_palette) self.setStyleSheet(""" QGroupBox { font-size: 14px; font-weight: bold; border: 2px solid #1E90FF; border-radius: 8px; margin-top: 1ex; color: #1E90FF; } QGroupBox::title { subcontrol-origin: margin; subcontrol-position: top center; padding: 0 5px; } QSlider::groove:horizontal { border: 1px solid #4A708B; height: 8px; background: #2F4F4F; margin: 2px 0; border-radius: 4px; } QSlider::handle:horizontal { background: #1E90FF; border: 1px solid #4A708B; width: 18px; margin: -4px 0; border-radius: 9px; } QPushButton { background-color: #1E90FF; color: white; border: none; border-radius: 4px; padding: 5px 10px; font-weight: bold; } QPushButton:hover { background-color: #00BFFF; } QLabel { color: white; } """) def create_control_panel(self): """创建控制面板""" panel = QGroupBox("GPS对抗控制面板") layout = QGridLayout() panel.setLayout(layout) # 卫星参数控制 satellite_label = QLabel("卫星参数:") satellite_label.setFont(QFont("Arial", 12, QFont.Bold)) layout.addWidget(satellite_label, 0, 0) # 卫星编号 sat_id_label = QLabel("卫星编号:") self.sat_id_spin = QSpinBox() self.sat_id_spin.setRange(1, 32) self.sat_id_spin.setValue(self.gps_system.satellite_id) self.sat_id_spin.valueChanged.connect(self.update_sat_id) layout.addWidget(sat_id_label, 1, 0) layout.addWidget(self.sat_id_spin, 1, 1) # 载波频率 freq_label = QLabel("载波频率 (MHz):") self.freq_spin = QDoubleSpinBox() self.freq_spin.setRange(1570, 1580) self.freq_spin.setValue(self.gps_system.carrier_freq) self.freq_spin.setSingleStep(0.01) self.freq_spin.valueChanged.connect(self.update_carrier_freq) layout.addWidget(freq_label, 2, 0) layout.addWidget(self.freq_spin, 2, 1) # 信号功率 power_label = QLabel("信号功率 (dBW):") self.power_slider = QSlider(Qt.Horizontal) self.power_slider.setRange(-170, -150) self.power_slider.setValue(int(self.gps_system.signal_power)) self.power_slider.valueChanged.connect(self.update_signal_power) layout.addWidget(power_label, 3, 0) layout.addWidget(self.power_slider, 3, 1) # 干扰参数控制 jam_label = QLabel("干扰参数:") jam_label.setFont(QFont("Arial", 12, QFont.Bold)) layout.addWidget(jam_label, 0, 2) # 干扰类型 jam_type_label = QLabel("干扰类型:") self.jam_type_combo = QComboBox() self.jam_type_combo.addItems(["None", "Narrowband", "Pulse", "Spoofing", "Swept"]) self.jam_type_combo.setCurrentText(self.gps_system.jamming_type) self.jam_type_combo.currentTextChanged.connect(self.update_jam_type) layout.addWidget(jam_type_label, 1, 2) layout.addWidget(self.jam_type_combo, 1, 3) # 干扰功率 jam_power_label = QLabel("干扰功率 (dBW):") self.jam_power_slider = QSlider(Qt.Horizontal) self.jam_power_slider.setRange(-150, -50) self.jam_power_slider.setValue(int(self.gps_system.jamming_power)) self.jam_power_slider.valueChanged.connect(self.update_jam_power) layout.addWidget(jam_power_label, 2, 2) layout.addWidget(self.jam_power_slider, 2, 3) # 干扰频率 jam_freq_label = QLabel("干扰频率 (MHz):") self.jam_freq_spin = QDoubleSpinBox() self.jam_freq_spin.setRange(1570, 1580) self.jam_freq_spin.setValue(self.gps_system.jamming_freq) self.jam_freq_spin.setSingleStep(0.01) self.jam_freq_spin.valueChanged.connect(self.update_jam_freq) layout.addWidget(jam_freq_label, 3, 2) layout.addWidget(self.jam_freq_spin, 3, 3) # 欺骗干扰参数 spoofing_label = QLabel("欺骗干扰参数:") spoofing_label.setFont(QFont("Arial", 12, QFont.Bold)) layout.addWidget(spoofing_label, 0, 4) # 欺骗延迟 spoofing_delay_label = QLabel("欺骗延迟 (ms):") self.spoofing_delay_spin = QDoubleSpinBox() self.spoofing_delay_spin.setRange(0.01, 1.0) self.spoofing_delay_spin.setValue(self.gps_system.spoofing_delay) self.spoofing_delay_spin.setSingleStep(0.01) self.spoofing_delay_spin.valueChanged.connect(self.update_spoofing_delay) layout.addWidget(spoofing_delay_label, 1, 4) layout.addWidget(self.spoofing_delay_spin, 1, 5) # 虚假卫星数量 spoofing_count_label = QLabel("虚假卫星数量:") self.spoofing_count_spin = QSpinBox() self.spoofing_count_spin.setRange(1, 5) self.spoofing_count_spin.setValue(self.gps_system.spoofing_count) self.spoofing_count_spin.valueChanged.connect(self.update_spoofing_count) layout.addWidget(spoofing_count_label, 2, 4) layout.addWidget(self.spoofing_count_spin, 2, 5) # 环境参数控制 env_label = QLabel("环境参数:") env_label.setFont(QFont("Arial", 12, QFont.Bold)) layout.addWidget(env_label, 5, 0) # 电离层延迟 iono_label = QLabel("电离层延迟 (ns):") self.iono_slider = QSlider(Qt.Horizontal) self.iono_slider.setRange(0, 20) self.iono_slider.setValue(int(self.gps_system.iono_delay)) self.iono_slider.valueChanged.connect(self.update_iono_delay) layout.addWidget(iono_label, 6, 0) layout.addWidget(self.iono_slider, 6, 1) # 多径效应 multipath_label = QLabel("多径效应幅度:") self.multipath_slider = QSlider(Qt.Horizontal) self.multipath_slider.setRange(0, 100) self.multipath_slider.setValue(int(self.gps_system.multipath * 100)) self.multipath_slider.valueChanged.connect(self.update_multipath) layout.addWidget(multipath_label, 7, 0) layout.addWidget(self.multipath_slider, 7, 1) # 系统参数 sys_label = QLabel("系统参数:") sys_label.setFont(QFont("Arial", 12, QFont.Bold)) layout.addWidget(sys_label, 5, 2) # 采样率 sample_rate_label = QLabel("采样率 (MS/s):") self.sample_rate_spin = QDoubleSpinBox() self.sample_rate_spin.setRange(50, 200) self.sample_rate_spin.setValue(self.gps_system.sample_rate) self.sample_rate_spin.setSingleStep(10) self.sample_rate_spin.valueChanged.connect(self.update_sample_rate) layout.addWidget(sample_rate_label, 6, 2) layout.addWidget(self.sample_rate_spin, 6, 3) # 噪声功率 noise_label = QLabel("热噪声功率 (dBW):") self.noise_slider = QSlider(Qt.Horizontal) self.noise_slider.setRange(-210, -150) self.noise_slider.setValue(int(self.gps_system.noise_power)) self.noise_slider.valueChanged.connect(self.update_noise_power) layout.addWidget(noise_label, 7, 2) layout.addWidget(self.noise_slider, 7, 3) # 控制按钮 self.reset_btn = QPushButton("重置参数") self.reset_btn.clicked.connect(self.reset_params) layout.addWidget(self.reset_btn, 8, 0, 1, 2) self.auto_jam_btn = QPushButton("自动干扰") self.auto_jam_btn.clicked.connect(self.toggle_auto_jam) layout.addWidget(self.auto_jam_btn, 8, 2, 1, 2) self.optimize_btn = QPushButton("优化定位") self.optimize_btn.clicked.connect(self.optimize_positioning) layout.addWidget(self.optimize_btn, 8, 4, 1, 2) self.auto_jam_active = False return panel def create_signal_panel(self): """创建信号显示面板""" panel = QGroupBox("GPS信号与干扰信号") layout = QHBoxLayout() panel.setLayout(layout) # 原始信号波形图 self.signal_fig = Figure(figsize=(10, 4), dpi=100) self.signal_canvas = FigureCanvas(self.signal_fig) self.signal_ax = self.signal_fig.add_subplot(111) self.signal_ax.set_title("原始GPS信号") self.signal_ax.set_xlabel("时间 (ms)") self.signal_ax.set_ylabel("幅度") self.signal_ax.grid(True, linestyle='--', alpha=0.6) layout.addWidget(self.signal_canvas) # 干扰信号波形图 self.jamming_fig = Figure(figsize=(10, 4), dpi=100) self.jamming_canvas = FigureCanvas(self.jamming_fig) self.jamming_ax = self.jamming_fig.add_subplot(111) self.jamming_ax.set_title("干扰信号") self.jamming_ax.set_xlabel("时间 (ms)") self.jamming_ax.set_ylabel("幅度") self.jamming_ax.grid(True, linestyle='--', alpha=0.6) layout.addWidget(self.jamming_canvas) # 合成信号波形图 self.combined_fig = Figure(figsize=(10, 4), dpi=100) self.combined_canvas = FigureCanvas(self.combined_fig) self.combined_ax = self.combined_fig.add_subplot(111) self.combined_ax.set_title("合成信号 (GPS + 干扰)") self.combined_ax.set_xlabel("时间 (ms)") self.combined_ax.set_ylabel("幅度") self.combined_ax.grid(True, linestyle='--', alpha=0.6) layout.addWidget(self.combined_canvas) return panel def create_position_panel(self): """创建位置显示面板""" panel = QGroupBox("定位信息") layout = QHBoxLayout() panel.setLayout(layout) # 三维位置图 self.position_fig = Figure(figsize=(8, 6), dpi=100) self.position_canvas = FigureCanvas(self.position_fig) self.position_ax = self.position_fig.add_subplot(111, projection='3d') self.position_ax.set_title("卫星与用户位置") self.position_ax.set_xlabel("X (km)") self.position_ax.set_ylabel("Y (km)") self.position_ax.set_zlabel("Z (km)") self.position_ax.grid(True, linestyle='--', alpha=0.6) layout.addWidget(self.position_canvas) # 定位误差图 self.error_fig = Figure(figsize=(6, 6), dpi=100) self.error_canvas = FigureCanvas(self.error_fig) self.error_ax = self.error_fig.add_subplot(111) self.error_ax.set_title("定位误差分布") self.error_ax.set_xlabel("X误差 (m)") self.error_ax.set_ylabel("Y误差 (m)") self.error_ax.grid(True, linestyle='--', alpha=0.6) layout.addWidget(self.error_canvas) return panel def create_status_panel(self): """创建状态显示面板""" panel = QFrame() panel.setFrameShape(QFrame.StyledPanel) layout = QHBoxLayout() panel.setLayout(layout) # 定位状态 position_status = QGroupBox("定位状态") pos_layout = QVBoxLayout() position_status.setLayout(pos_layout) self.position_label = QLabel("定位模式: 三维定位") self.position_label.setFont(QFont("Arial", 14)) self.position_label.setStyleSheet("color: #00FF00;") pos_layout.addWidget(self.position_label) self.pdop_label = QLabel("PDOP: 1.0") self.pdop_label.setFont(QFont("Arial", 12)) pos_layout.addWidget(self.pdop_label) self.hdop_label = QLabel("HDOP: 0.8") self.hdop_label.setFont(QFont("Arial", 12)) pos_layout.addWidget(self.hdop_label) self.vdop_label = QLabel("VDOP: 0.6") self.vdop_label.setFont(QFont("Arial", 12)) pos_layout.addWidget(self.vdop_label) layout.addWidget(position_status) # 干扰状态 jam_status = QGroupBox("干扰状态") jam_layout = QVBoxLayout() jam_status.setLayout(jam_layout) self.jam_status_label = QLabel("干扰强度: 弱") self.jam_status_label.setFont(QFont("Arial", 14)) self.jam_status_label.setStyleSheet("color: #FFA500;") jam_layout.addWidget(self.jam_status_label) self.jam_power_label = QLabel("干扰功率: -100 dBW") self.jam_power_label.setFont(QFont("Arial", 12)) jam_layout.addWidget(self.jam_power_label) self.jam_effect_label = QLabel("干扰效果: 无") self.jam_effect_label.setFont(QFont("Arial", 12)) jam_layout.addWidget(self.jam_effect_label) layout.addWidget(jam_status) # 系统状态 sys_status = QGroupBox("系统状态") sys_layout = QVBoxLayout() sys_status.setLayout(sys_layout) self.sys_status_label = QLabel("系统运行: 正常") self.sys_status_label.setFont(QFont("Arial", 14)) self.sys_status_label.setStyleSheet("color: #00FF00;") sys_layout.addWidget(self.sys_status_label) self.sample_rate_status = QLabel("采样率: 100 MS/s") self.sample_rate_status.setFont(QFont("Arial", 12)) sys_layout.addWidget(self.sample_rate_status) self.freq_range_status = QLabel("频率范围: 1570-1580 MHz") self.freq_range_status.setFont(QFont("Arial", 12)) sys_layout.addWidget(self.freq_range_status) layout.addWidget(sys_status) return panel def update_simulation(self): """更新仿真数据并刷新界面""" # 生成信号数据 t, signal = self.gps_system.generate_gps_signal() jamming_signal = self.gps_system.generate_interference(t) combined_signal = signal + jamming_signal # 计算定位信息 estimated_pos = self.gps_system.calculate_position() pdop, hdop, vdop = self.gps_system.calculate_dop() # 计算干扰强度 jam_power = 10 ** (self.gps_system.jamming_power / 10) # 更新波形图 self.update_waveform_plot(t, signal, jamming_signal, combined_signal) # 更新位置图 self.update_position_plot(estimated_pos) # 更新状态显示 self.update_status(jam_power, pdop, hdop, vdop) # 自动干扰模式 if self.auto_jam_active: self.auto_jamming() def update_waveform_plot(self, t, signal, jamming_signal, combined_signal): """更新波形图""" # 原始信号 self.signal_ax.clear() self.signal_ax.plot(t, signal, 'b-', linewidth=1.5) self.signal_ax.set_title("原始GPS信号") self.signal_ax.set_xlabel("时间 (ms)") self.signal_ax.set_ylabel("幅度") self.signal_ax.grid(True, linestyle='--', alpha=0.6) self.signal_ax.set_xlim(0, self.gps_system.duration) self.signal_canvas.draw() # 干扰信号 self.jamming_ax.clear() self.jamming_ax.plot(t, jamming_signal, 'r-', linewidth=1.5) self.jamming_ax.set_title("干扰信号") self.jamming_ax.set_xlabel("时间 (ms)") self.jamming_ax.set_ylabel("幅度") self.jamming_ax.grid(True, linestyle='--', alpha=0.6) self.jamming_ax.set_xlim(0, self.gps_system.duration) self.jamming_canvas.draw() # 合成信号 self.combined_ax.clear() self.combined_ax.plot(t, combined_signal, 'g-', linewidth=1.5) self.combined_ax.set_title("合成信号 (GPS + 干扰)") self.combined_ax.set_xlabel("时间 (ms)") self.combined_ax.set_ylabel("幅度") self.combined_ax.grid(True, linestyle='--', alpha=0.6) self.combined_ax.set_xlim(0, self.gps_system.duration) self.combined_canvas.draw() def update_position_plot(self, estimated_pos): """更新位置图""" # 清除旧的图形 self.position_ax.clear() # 设置标题和标签 self.position_ax.set_title("卫星与用户位置") self.position_ax.set_xlabel("X (km)") self.position_ax.set_ylabel("Y (km)") self.position_ax.set_zlabel("Z (km)") self.position_ax.grid(True, linestyle='--', alpha=0.6) # 设置坐标轴范围 self.position_ax.set_xlim(0, 25000) self.position_ax.set_ylim(0, 25000) self.position_ax.set_zlim(0, 25000) # 绘制卫星位置 satellite_pos = self.gps_system.satellite_pos self.position_ax.scatter(satellite_pos[0], satellite_pos[1], satellite_pos[2], c='red', s=100, marker='^', label='卫星') # 绘制用户真实位置 user_pos = self.gps_system.user_pos self.position_ax.scatter(user_pos[0], user_pos[1], user_pos[2], c='blue', s=100, marker='o', label='真实位置') # 绘制估计位置 self.position_ax.scatter(estimated_pos[0], estimated_pos[1], estimated_pos[2], c='green', s=100, marker='x', label='估计位置') # 添加图例 self.position_ax.legend() # 更新画布 self.position_canvas.draw() # 更新误差图 error = estimated_pos - user_pos self.error_ax.clear() self.error_ax.plot(error[0] * 1000, error[1] * 1000, 'ro', markersize=10) self.error_ax.set_title("定位误差分布") self.error_ax.set_xlabel("X误差 (m)") self.error_ax.set_ylabel("Y误差 (m)") self.error_ax.axis('equal') self.error_ax.grid(True, linestyle='--', alpha=0.6) self.error_ax.set_xlim(-100, 100) self.error_ax.set_ylim(-100, 100) self.error_canvas.draw() def update_status(self, jam_power, pdop, hdop, vdop): """更新状态显示""" # 更新DOP值 self.pdop_label.setText(f"PDOP: {pdop:.2f}") self.hdop_label.setText(f"HDOP: {hdop:.2f}") self.vdop_label.setText(f"VDOP: {vdop:.2f}") # 定位精度评估 if pdop < 2: self.position_label.setText("定位模式: 精密定位") self.position_label.setStyleSheet("color: #00FF00;") elif pdop < 5: self.position_label.setText("定位模式: 良好定位") self.position_label.setStyleSheet("color: #7CFC00;") elif pdop < 10: self.position_label.setText("定位模式: 一般定位") self.position_label.setStyleSheet("color: #FFD700;") else: self.position_label.setText("定位模式: 低精度定位") self.position_label.setStyleSheet("color: #FF4500;") # 干扰状态 self.jam_power_label.setText(f"干扰功率: {self.gps_system.jamming_power} dBW") if jam_power < 1e-12: # -120 dBW self.jam_status_label.setText("干扰强度: 无") self.jam_status_label.setStyleSheet("color: #00FF00;") elif jam_power < 1e-10: # -100 dBW self.jam_status_label.setText("干扰强度: 弱") self.jam_status_label.setStyleSheet("color: #7CFC00;") elif jam_power < 1e-8: # -80 dBW self.jam_status_label.setText("干扰强度: 中") self.jam_status_label.setStyleSheet("color: #FFA500;") else: self.jam_status_label.setText("干扰强度: 强") self.jam_status_label.setStyleSheet("color: #FF4500;") # 干扰效果评估 if pdop > 10: self.jam_effect_label.setText("干扰效果: 严重") elif pdop > 5: self.jam_effect_label.setText("干扰效果: 显著") elif pdop > 2: self.jam_effect_label.setText("干扰效果: 轻微") else: self.jam_effect_label.setText("干扰效果: 无") # 系统状态 self.sample_rate_status.setText(f"采样率: {self.gps_system.sample_rate} MS/s") def auto_jamming(self): """自动干扰模式""" # 随机改变干扰参数 if np.random.rand() < 0.1: self.jam_type_combo.setCurrentIndex(np.random.randint(1, 5)) if np.random.rand() < 0.2: new_freq = max(1570, min(1580, self.gps_system.jamming_freq + np.random.uniform(-0.5, 0.5))) self.jam_freq_spin.setValue(new_freq) if np.random.rand() < 0.3: new_power = max(-150, min(-50, self.gps_system.jamming_power + np.random.randint(-5, 5))) self.jam_power_slider.setValue(int(new_power)) if self.gps_system.jamming_type == "Spoofing" and np.random.rand() < 0.2: new_delay = max(0.01, min(1.0, self.gps_system.spoofing_delay + np.random.uniform(-0.05, 0.05))) self.spoofing_delay_spin.setValue(new_delay) if self.gps_system.jamming_type == "Spoofing" and np.random.rand() < 0.1: new_count = max(1, min(5, self.gps_system.spoofing_count + np.random.randint(-1, 2))) self.spoofing_count_spin.setValue(new_count) def toggle_auto_jam(self): """切换自动干扰模式""" self.auto_jam_active = not self.auto_jam_active if self.auto_jam_active: self.auto_jam_btn.setText("停止干扰") self.auto_jam_btn.setStyleSheet("background-color: #FF4500;") else: self.auto_jam_btn.setText("自动干扰") self.auto_jam_btn.setStyleSheet("") def optimize_positioning(self): """优化定位参数""" # 简单优化策略:避开干扰频率 if self.gps_system.jamming_type != "None" and self.gps_system.jamming_freq > 0: # 尝试调整卫星编号以避开干扰 new_id = (self.gps_system.satellite_id % 32) + 1 self.sat_id_spin.setValue(new_id) self.position_label.setText("定位模式: 卫星切换中") def reset_params(self): """重置参数到默认值""" self.gps_system = GPSSystem() # 重置卫星参数 self.sat_id_spin.setValue(self.gps_system.satellite_id) self.freq_spin.setValue(self.gps_system.carrier_freq) self.power_slider.setValue(int(self.gps_system.signal_power)) # 重置干扰参数 self.jam_type_combo.setCurrentText(self.gps_system.jamming_type) self.jam_power_slider.setValue(int(self.gps_system.jamming_power)) self.jam_freq_spin.setValue(self.gps_system.jamming_freq) self.spoofing_delay_spin.setValue(self.gps_system.spoofing_delay) self.spoofing_count_spin.setValue(self.gps_system.spoofing_count) # 重置环境参数 self.iono_slider.setValue(int(self.gps_system.iono_delay)) self.multipath_slider.setValue(int(self.gps_system.multipath * 100)) # 重置系统参数 self.sample_rate_spin.setValue(self.gps_system.sample_rate) self.noise_slider.setValue(int(self.gps_system.noise_power)) # 重置自动干扰状态 self.auto_jam_active = False self.auto_jam_btn.setText("自动干扰") self.auto_jam_btn.setStyleSheet("") # 参数更新函数 def update_sat_id(self, value): self.gps_system.satellite_id = value def update_carrier_freq(self, value): self.gps_system.carrier_freq = value def update_signal_power(self, value): self.gps_system.signal_power = value def update_jam_type(self, text): self.gps_system.jamming_type = text def update_jam_power(self, value): self.gps_system.jamming_power = value def update_jam_freq(self, value): self.gps_system.jamming_freq = value def update_spoofing_delay(self, value): self.gps_system.spoofing_delay = value def update_spoofing_count(self, value): self.gps_system.spoofing_count = value def update_iono_delay(self, value): self.gps_system.iono_delay = value def update_multipath(self, value): self.gps_system.multipath = value / 100.0 def update_sample_rate(self, value): self.gps_system.sample_rate = value def update_noise_power(self, value): self.gps_system.noise_power = value if __name__ == "__main__": app = QApplication(sys.argv) window = GPSJammingSimulator() window.show() sys.exit(app.exec_())
10-13
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2025/5/10 22:56 # @File : gui.py import datetime import shutil import traceback import warnings import torch import threading import os.path as osp from PyQt5.QtGui import * from pathlib import Path from PyQt5 import QtCore from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QLabel import os import sys from PyQt5.QtCore import QTimer, Qt import cv2 from detect import detect_image, load_model, init_model_ocr from ui import Ui_MainWindow FILE = Path(__file__).resolve() ROOT = FILE.parents[0] if str(ROOT) not in sys.path: sys.path.append(str(ROOT)) # add ROOT to PATH ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative warnings.filterwarnings('ignore') os.environ['KMP_DUPLICATE_LIB_OK'] = 'True' class MyWindow(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") self.stop = False self.file_path = "" # 图片读取进程 self.output_size = 640 self.img2predict = "" # 更新视频图像 self.timer_camera = QTimer() self.cap = None self.is_camera_open = False self.stopEvent = threading.Event() # 加载检测模型 self.model = None self.conf_threshold = 0.25 self.setupUi(self) self.setWindowFlag(QtCore.Qt.FramelessWindowHint) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.pushButton.clicked.connect(self.upload_img) self.pushButton_2.clicked.connect(self.detect_img) self.pushButton_5.clicked.connect(self.vedio_show) # self.pushButton_9.clicked.connect(self.camera_show) self.pushButton_10.clicked.connect(self.video_stop) self.pushButton_3.clicked.connect(self.close_window) self.reset_vid() self._device = torch.device("cuda" if torch.cuda.is_available() else "cpu") self._detect_model = load_model('./weights/detect.pt', self._device) self._plate_rec_model = init_model_ocr(self._device, './weights/cars_number.pth') def upload_img(self): """上传图片""" # 选择录像文件进行读取 fileName, fileType = QFileDialog.getOpenFileName(self, 'Choose file', '', '*.jpg *.png *.tif *.jpeg') if fileName: self.file_path = fileName suffix = fileName.split(".")[-1] save_path = osp.join("images/tmp", "tmp_upload." + suffix) shutil.copy(fileName, save_path) # 应该调整一下图片的大小,然后统一放在一起 im0 = cv2.imread(save_path) resize_scale = self.output_size / im0.shape[0] im0 = cv2.resize(im0, (0, 0), fx=resize_scale, fy=resize_scale) cv2.imwrite("images/tmp/upload_show_result.jpg", im0) self.img2predict = fileName self.label_5.setScaledContents(True) self.label_5.setPixmap(QPixmap("images/tmp/upload_show_result.jpg")) # todo 上传图片之后右侧的图片重置, self.label_6.setText(' ') def detect_img(self): """检测图片""" org_path = self.file_path # 目标检测 try: now_img, infos = detect_image(org_path, self._detect_model, self._plate_rec_model, self._device) for info in infos: self.add_log(f'{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")} - {info[0]} - {info[1]} - 车牌位置:{info[2]} - 置信度:{info[3]}') except: print(traceback.format_exc()) return cv2.imwrite("images/tmp/single_result.jpg", now_img) self.label_6.setScaledContents(True) self.label_6.setPixmap(QPixmap("images/tmp/single_result.jpg")) def get_video_path(self): file_path, _ = QFileDialog.getOpenFileName(None, '打开视频', './', "Image files (*.avi *.mp4)") if not file_path: return None self.org_path = file_path return file_path def video_start(self): # 定时器开启,每隔一段时间,读取一帧 self.timer_camera.start(1) self.timer_camera.timeout.connect(self.open_frame) def video_stop(self): self.cap.release() self.timer_camera.stop() self.reset_vid() def open_frame(self): ret, now_img = self.cap.read() if ret: # 目标检测 try: now_img2, infos = detect_image(now_img, self._detect_model, self._plate_rec_model, self._device) for info in infos: self.add_log( f'{datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")} - {info[0]} - {info[1]} - 车牌位置:{info[2]} - 置信度:{info[3]}') except: print(traceback.format_exc()) return cv2.imwrite("images/tmp/single_result_vid.jpg", now_img2) self.label_8.clear() self.label_8.setScaledContents(True) self.label_8.setPixmap(QPixmap("images/tmp/single_result_vid.jpg")) else: self.cap.release() self.timer_camera.stop() def vedio_show(self): if self.is_camera_open: self.is_camera_open = False print('摄像头未开启') video_path = self.get_video_path() if not video_path: return None self.cap = cv2.VideoCapture(video_path) self.video_start() def camera_show(self): self.is_camera_open = not self.is_camera_open if self.is_camera_open: print('摄像头开启') self.cap = cv2.VideoCapture(0) self.video_start() else: print('摄像头未开启') self.label_8.setText('') if self.cap: self.cap.release() cv2.destroyAllWindows() self.label_8.clear() def close_window(self): self.stopEvent.set() self.close() def reset_vid(self): """界面重置事件""" self.pushButton_5.setEnabled(True) # self.pushButton_9.setEnabled(True) # self.label_8.setText('检测窗口') def add_log(self, message): label = QLabel(message) label.setWordWrap(True) # 自动换行 label.setStyleSheet("padding: 4px; font-size: 12px; color: #333;") self.scrollLayout.addWidget(label) # 可选:自动滚动到底部 self.scrollArea.verticalScrollBar().setValue( self.scrollArea.verticalScrollBar().maximum() ) def start_pyqt_app(): QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) app = QApplication(sys.argv) my_window = MyWindow() my_window.show() sys.exit(app.exec_()) if __name__ == '__main__': # 解决2K等高分辨率屏幕不匹配或自适应问题,导致部分控件显示不完全 QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) app = QApplication(sys.argv) my_window = MyWindow() my_window.show() sys.exit(app.exec_())解释这段代码并列出其核心功能
05-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值