以下是带有简要注释的代码:
```c
/* 版权声明和文件描述 */
/* 文件名称:main.c
描述:本文件是项目的主功能文件
作者:葛宏宝
版本:1.0.0
日期:2024年8月15日 */
#include <stdio.h>
#include <gtk/gtk.h> /* GTK图形库头文件 */
#include <pthread.h> /* POSIX线程库头文件 */
#include <stdlib.h> /* 标准库头文件 */
#include <fcntl.h> /* 文件控制定义 */
#include <termios.h> /* 与终端设备交互接口 */
#include <cairo.h> /* Cairo绘图库 */
#include <math.h> /* 数学函数头文件 */
/***************************************************************************************/
/* 定义常量 */
/***************************************************************************************/
#define NUMS_OF_THREADS 10 /* 线程数量定义 */
#define DIAGRAM_WIDTH 600 /* 图表宽度 */
#define DIAGRAM_HEIGHT 300 /* 图表高度 */
/***************************************************************************************/
/* 结构体定义 */
/***************************************************************************************/
typedef struct {
GtkWidget *diagram; /* 图形组件指针 */
double phase; /* 相位变量 */
} MyData;
/***************************************************************************************/
/* 全局变量 */
/***************************************************************************************/
static int cmd_is_starting = 0; /* 命令是否正在启动标记 */
int serial_port; /* 串口句柄 */
static char port[10] = "/dev/ttyS0";/* 串口号 */
static GtkWidget *progress; /* 进度条控件 */
pthread_t threads[NUMS_OF_THREADS]; /* 线程数组 */
int thread_id[NUMS_OF_THREADS]; /* 线程标识号 */
thread_id[0] = 1; /* 第一个线程标识为1 */
/***************************************************************************************/
/* 函数实现部分 */
/***************************************************************************************/
// 初始化串口,并配置相关属性
static void port_init(int *serial_port , char *port){
return; /* 注释掉实际串口操作,这里不做具体实现 */
// 下面是被注释掉的实际代码逻辑:
// 打开指定串口并获取文件描述符,如果失败则退出程序
// 设置波特率等串口参数
}
// 在命令行窗口执行结束后更新GUI状态
static gboolean on_serial_done(gpointer data) {
GtkWidget *button = GTK_WIDGET(data);
cmd_is_starting = 0;
gtk_button_set_label(GTK_BUTTON(button), "开始");
return FALSE;
}
// 点击按钮触发的回调函数,启动命令行进程
static void cmd_start(GtkWidget *widget, gpointer data){
GtkWidget *button = GTK_WIDGET(data);
if (cmd_is_starting == 1){
gtk_button_set_label(GTK_BUTTON(button), "程序正在运行中..., 请不要重复点击");
return;
}
cmd_is_starting = 1;
gtk_button_set_label(GTK_BUTTON(button), "程序正在运行中..., 请稍后");
write(serial_port, "start", 5);
if (pthread_create(&threads[0], NULL, cmd_window, (void*)&thread_id[0]) != 0){
perror("窗口打开失败");
exit(1);
}
g_timeout_add(5000, (GSourceFunc)on_serial_done, button);
}
// 绘图回调函数,在窗口绘制波形图
static gboolean draw_cb(GtkWidget *widget, cairo_t *cr, gpointer user_data){
MyData *data = (MyData*)user_data;
double x, y;
/* 绘制背景 */
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_paint(cr);
/* 设置曲线颜色 */
cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
/* 设置曲线宽度 */
cairo_set_line_width(cr, 2.0);
/* 绘制波形 */
for(x = 0; x < DIAGRAM_WIDTH; x++){
double rad = x * (2.0 * M_PI / DIAGRAM_WIDTH);
double val = sin(rad + data->phase);
y = DIAGRAM_HEIGHT / 2 + (DIAGRAM_HEIGHT / 4) * val;
if (x == 0)
cairo_move_to(cr, x, y);
else
cairo_line_to(cr, x, y);
}
cairo_stroke(cr);
/* 更新相位以模拟动态效果 */
data->phase += 0.1;
/* 返回TRUE以继续接收绘图事件 */
return TRUE;
}
// 定时器回调函数,用于定期重绘图表
static gboolean timer_cb(gpointer data) {
gtk_widget_queue_draw((GtkWidget *)data);
return TRUE;
}
// 创建线程用于执行命令行窗口
static void* cmd_window(void *data){
double i = 1.0;
while (i > 0) {
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 1.0 - i);
sleep(1);
i -= 0.2;
}
return NULL;
}
/***************************************************************************************/
/* 主函数 */
/***************************************************************************************/
int main(int argc, char *argv[]){
gtk_init(&argc, &argv); /* 初始化GTK */
port_init(&serial_port, port); /* 初始化串口 */
/* 创建主窗口 */
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Simple GTK Window");
gtk_window_set_default_size(GTK_WINDOW(window), 1024, 512);
/* 创建网格布局 */
GtkWidget *grid = gtk_grid_new();
gtk_container_add(GTK_CONTAINER(window), grid);
/* 创建标签 */
GtkWidget *label = gtk_label_new("Hello, World!");
gtk_grid_attach(GTK_GRID(grid), label, 1, 3, 1, 1);
/* 创建按钮 */
GtkWidget *button = gtk_button_new();
gtk_button_set_label(GTK_BUTTON(button), "开始");
gtk_grid_attach(GTK_GRID(grid), button, 0, 3, 1, 1);
g_signal_connect(button, "clicked", G_CALLBACK(cmd_start), button);
/* 创建进度条 */
progress = gtk_progress_bar_new();
gtk_grid_attach(GTK_GRID(grid), progress, 0, 4, 5, 1);
/* 创建多个绘图区 */
GtkWidget *diagram = gtk_drawing_area_new();
GtkWidget *diagram_son = gtk_drawing_area_new();
GtkWidget *diagram_son_high = gtk_drawing_area_new();
GtkWidget *diagram_son_media = gtk_drawing_area_new();
GtkWidget *diagram_son_low = gtk_drawing_area_new();
/* 为绘图区设置框架 */
GtkWidget *diagram_out = gtk_frame_new("原始曲线");
GtkWidget *diagram_son = gtk_frame_new("噪声曲线");
GtkWidget *diagram_son_high_out = gtk_frame_new("分解曲线——高频");
GtkWidget *diagram_son_media_out = gtk_frame_new("分解曲线——中频");
GtkWidget *diagram_son_low_out = gtk_frame_new("分解曲线——低频");
/* 将绘图区加入到对应的框架内 */
gtk_container_add(GTK_CONTAINER(diagram_out), diagram);
gtk_container_add(GTK_CONTAINER(diagram_son), diagram_son_high);
gtk_container_add(GTK_CONTAINER(diagram_son_high_out), diagram_son_high);
gtk_container_add(GTK_CONTAINER(diagram_son_media_out), diagram_son_media);
gtk_container_add(GTK_CONTAINER(diagram_son_low_out), diagram_son_low);
/* 设置绘图区大小 */
gtk_widget_set_size_request(diagram, DIAGRAM_WIDTH, DIAGRAM_HEIGHT);
gtk_widget_set_size_request(diagram_son, DIAGRAM_WIDTH, DIAGRAM_HEIGHT/2);
gtk_widget_set_size_request(diagram_son_high, DIAGRAM_WIDTH, DIAGRAM_HEIGHT/2);
gtk_widget_set_size_request(diagram_son_media, DIAGRAM_WIDTH, DIAGRAM_HEIGHT/2);
gtk_widget_set_size_request(diagram_son_low, DIAGRAM_WIDTH, DIAGRAM_HEIGHT/2);
/* 将绘图区及其框架放入网格布局中 */
gtk_grid_attach(GTK_GRID(grid), diagram_out, 0, 0, 5, 2);
gtk_grid_attach(GTK_GRID(grid), diagram_son, 0, 2, 5, 1);
gtk_grid_attach(GTK_GRID(grid), diagram_son_high_out, 6, 0, 5, 1);
gtk_grid_attach(GTK_GRID(grid), diagram_son_media_out, 6, 1, 5, 1);
gtk_grid_attach(GTK_GRID(grid), diagram_son_low_out, 6, 2, 5, 1);
/* 初始化MyData结构体 */
MyData my_data;
my_data.diagram = diagram;
my_data.phase = 0.0;
/* 设置绘图回调函数 */
g_signal_connect(diagram, "draw", G_CALLBACK(draw_cb), &my_data);
/* 添加定时器,每0.5秒更新一次波形 */
g_timeout_add(500, timer_cb, diagram);
/* 显示所有窗口元素 */
gtk_widget_show_all(window);
/* 启动GTK主循环 */
gtk_main();
/* 等待线程结束 */
pthread_join(threads[0], NULL);
printf("线程结束");
return 0;
}
```