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

Linux内核开发者求助:用GTK实现CISPR测试全屏滚动H

实现全屏黑底滚动"H"的GTK方案

作为Linux内核开发者,你已经搭好了全屏黑屏的基础框架,这点很棒!要实现滚动的"H"效果,我们可以基于现有代码,用几个GTK/GLib的工具就能轻松搞定,下面一步步给你拆解:

核心组件与工具

  • GtkFixed:替代默认容器,让我们能精准控制"H"的坐标位置(默认容器会自动布局,不适合自定义滚动路径)
  • GtkLabel:继续用它显示"H",比自定义绘制更简单上手,适合GUI新手
  • g_timeout_add():GLib的定时器函数,定时更新标签位置,形成连续滚动动画
  • Pango字体工具:调整"H"的大小和样式,让它在测试中更清晰

具体修改步骤

1. 替换布局容器为GtkFixed

原来的代码直接把Label加到Window里,Window默认用的是自动布局容器,我们换成GtkFixed来手动控制位置:

// 替换原有的gtk_container_add部分
GtkWidget *fixed = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), fixed);
gtk_container_add(GTK_CONTAINER(fixed), label);

2. 初始化滚动位置变量

在main函数开头定义静态变量跟踪"H"的位置(单线程GTK程序里静态变量足够安全):

static int pos_x = 0;  // 水平滚动位置
static int pos_y;      // 垂直居中位置

窗口显示后,计算垂直居中的Y坐标,同时把"H"初始位置放在窗口左侧外,准备滚动进入:

// 在gtk_widget_show_all(window)之后添加:
int win_width, win_height;
gtk_window_get_size(GTK_WINDOW(window), &win_width, &win_height);
int label_width, label_height;
gtk_widget_get_size_request(label, &label_width, &label_height);
// 垂直居中
pos_y = (win_height - label_height) / 2;
// 初始位置在窗口左侧外
pos_x = -label_width;
gtk_fixed_move(GTK_FIXED(fixed), label, pos_x, pos_y);

3. 编写滚动动画回调函数

写一个函数定时更新位置,让"H"从左向右滚动,滚出右侧后重新从左侧进入:

gboolean scroll_h(gpointer user_data) {
    GtkWidget *fixed = GTK_WIDGET(user_data);
    GtkWidget *label = gtk_bin_get_child(GTK_BIN(fixed));
    int win_width;
    gtk_window_get_size(GTK_WINDOW(gtk_widget_get_toplevel(fixed)), &win_width, NULL);
    int label_width;
    gtk_widget_get_size_request(label, &label_width, NULL);

    pos_x += 5;  // 滚动速度,数值越大越快,可根据需求调整
    if (pos_x > win_width) {
        pos_x = -label_width;  // 滚出屏幕后重置到左侧外
    }
    gtk_fixed_move(GTK_FIXED(fixed), label, pos_x, pos_y);
    return G_SOURCE_CONTINUE;  // 保持定时器持续触发
}

4. 启动动画定时器

在窗口初始化完成后,添加定时器控制帧率(比如每30毫秒更新一次,接近30帧/秒的流畅度):

// 设置完初始位置后添加
g_timeout_add(30, scroll_h, fixed);

5. 调整标签样式

把"H"改成白色、大字体,背景设为黑色,匹配测试需求:

// 创建Label后添加:
gtk_label_set_text(GTK_LABEL(label), "H");
// 设置48号字体,可根据屏幕大小调整
PangoFontDescription *font = pango_font_description_from_string("Sans 48");
gtk_widget_modify_font(label, font);
pango_font_description_free(font);
// 黑底白字
gtk_widget_modify_bg(label, GTK_STATE_NORMAL, &gdk_color_black);
gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gdk_color_white);

完整修改后的代码示例

#include <gtk/gtk.h>
#include <pango/pango.h>

static int pos_x = 0;
static int pos_y;

gboolean scroll_h(gpointer user_data) {
    GtkWidget *fixed = GTK_WIDGET(user_data);
    GtkWidget *label = gtk_bin_get_child(GTK_BIN(fixed));
    int win_width;
    gtk_window_get_size(GTK_WINDOW(gtk_widget_get_toplevel(fixed)), &win_width, NULL);
    int label_width;
    gtk_widget_get_size_request(label, &label_width, NULL);

    pos_x += 5;
    if (pos_x > win_width) {
        pos_x = -label_width;
    }
    gtk_fixed_move(GTK_FIXED(fixed), label, pos_x, pos_y);
    return G_SOURCE_CONTINUE;
}

int main (int argc, char *argv[]) {
    GtkWidget *window;
    GtkWidget *label;
    GtkWidget *fixed;

    gtk_init (&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
    // 窗口背景设为黑色
    gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &gdk_color_black);

    // 创建Fixed布局容器
    fixed = gtk_fixed_new();
    gtk_container_add(GTK_CONTAINER(window), fixed);

    // 创建显示"H"的标签
    label = gtk_label_new("H");
    // 设置字体大小
    PangoFontDescription *font = pango_font_description_from_string("Sans 48");
    gtk_widget_modify_font(label, font);
    pango_font_description_free(font);
    // 设置标签黑底白字
    gtk_widget_modify_bg(label, GTK_STATE_NORMAL, &gdk_color_black);
    gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gdk_color_white);
    gtk_container_add(GTK_CONTAINER(fixed), label);

    // 隐藏光标
    GdkCursor* cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
    GdkWindow* win = gtk_widget_get_window(window);
    gdk_window_set_cursor(win, cursor);

    gtk_widget_show_all(window);

    // 计算初始位置
    int win_width, win_height;
    gtk_window_get_size(GTK_WINDOW(window), &win_width, &win_height);
    int label_width, label_height;
    gtk_widget_get_size_request(label, &label_width, &label_height);
    pos_y = (win_height - label_height) / 2;
    pos_x = -label_width;
    gtk_fixed_move(GTK_FIXED(fixed), label, pos_x, pos_y);

    // 启动滚动动画
    g_timeout_add(30, scroll_h, fixed);

    gtk_main();
    return 0;
}

编译注意事项

编译时需要链接GTK3和Pango库,用以下命令:

gcc -o scroll_h scroll_h.c `pkg-config --cflags --libs gtk+-3.0`

如果需要调整滚动方向(比如上下滚动),只需要把逻辑改成更新pos_y即可,非常灵活。

内容的提问来源于stack exchange,提问作者md.jamal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:48:53