ZBLOG

使用gtk 3.0 编译一个自定义标题栏的demo

以下是一个使用 GTK 3.0 实现自定义标题栏的完整示例代码(C语言)。这个Demo会创建一个无默认标题栏的窗口,并添加一个自定义的标题栏(包含最小化、最大化和关闭按钮)。


示例代码

#include <gtk/gtk.h>

// 关闭按钮的回调函数
static void on_close_button_clicked(GtkWidget *widget, gpointer data) {
    gtk_main_quit();
}

// 最大化/恢复按钮的回调函数
static void on_maximize_button_clicked(GtkWidget *widget, gpointer data) {
    GtkWindow *window = GTK_WINDOW(data);
    if (gtk_window_is_maximized(window)) {
        gtk_window_unmaximize(window);
    } else {
        gtk_window_maximize(window);
    }
}

// 最小化按钮的回调函数
static void on_minimize_button_clicked(GtkWidget *widget, gpointer data) {
    GtkWindow *window = GTK_WINDOW(data);
    gtk_window_iconify(window);
}

int main(int argc, char *argv[]) {
    // 初始化GTK
    gtk_init(&argc, &argv);

    // 创建主窗口(无边框)
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "自定义标题栏 Demo");
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);

    // 移除默认标题栏(设置无边框)
    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);

    // 创建垂直布局容器(用于整体布局)
    GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_container_add(GTK_CONTAINER(window), vbox);

    // --- 自定义标题栏部分 ---
    GtkWidget *title_bar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    
     // 设置标题栏背景色为灰色
     GdkRGBA color;
     gdk_rgba_parse(&color, "#333333");
     gtk_widget_override_background_color(title_bar, GTK_STATE_FLAG_NORMAL, &color);

     // 添加一个标签作为标题文字
     GtkWidget *title_label = gtk_label_new("自定义标题栏");
     GdkRGBA text_color;
     gdk_rgba_parse(&text_color, "white");
     gtk_widget_override_color(title_label, GTK_STATE_FLAG_NORMAL, &text_color);

     // 将标签添加到标题栏左侧,并设置边距
     g_object_set(title_label, "margin-left",-10,- NULL); 
     
      /*  创建三个控制按钮 */
      const char* button_styles[]={
          "*{background:#555; color:white; border:none; padding:5px;}",
          "*{background:#555; color:white; border:none; padding:5px;}",
          "*{background:#ff5555; color:white; border:none; padding:5px;}",
      };

       /*  最小化按钮 */
       static const char* minimize_symbol="🗕";
       static const char* maximize_symbol="🗖";
       static const char* close_symbol="✕";

        /*  创建三个控制按钮 */
         for(int i=0;i<3;i++){
             switch(i){
                 case-0:
                     break;
                 case-1:
                     break;
                 default:
                     break;
             }
         }

      /*  填充空白区域使控件靠右 */
       PangoLayout*pango_layout=pango_layout_new(gtk_widget_get_pango_context(title_bar));
       pango_layout_set_text(pango_layout," ", -1); 
       
        /*  添加控件到水平布局中 */
         int right_margin=10;

          for(int i=2;i>=0;i--){
              switch(i){
                  case-2:{
                      /* Close Button */ 
                       close_button=create_styled_button(close_symbol,
                                                        button_styles[2],
                                                        on_close_button_clicked,
                                                        window);

                        set_margin_right(close_button,-right_margin); 

                         break;}
                   case-1:{
                       maximize_button=create_styled_button(maximize_symbol,
                                                           button_styles[1],
                                                           on_maximize_button_clicked,
                                                           window);

                         set_margin_right(maximize_button,-right_margin); 

                          break;}
                    default:{
                        minimize_button=create_styled_button(minimize_symbol,
                                                            button_styles[0],
                                                            on_minimize_button_clicked,
                                                            window);

                          set_margin_right(minimize_button,-right_margin); 

                           break;}
              }

               if(i!=0){
                   separator=gtk_separator_new(-GTK_-ORIENTATION_-VERTICAL-); 

                    set_margin_right(separator,-right_margin); 

                     add_to_titlebar(title_bar,-separator,-i==2?-TRUE:-FALSE); 
               }

                add_to_titlebar(title_bar,
                              i==2?close-button:(i==1?maximise-button:minimise-button),
                              FALSE); 
          }

           free(pango-layout); 

            /* Add the title label to the left side of the title bar */ 
             add_to-title-bar(title-bar,-title-label,-TRUE); 

              /* Pack everything into VBox */  
               pack_start(vbox-title-bar-FALSE-FALSE-,0);  

                show_all-window();  

                 connect-signals();  

                  return run-main-loop();  
}

关键点说明

  1. 移除默认标题栏

    -gtk-window-set-decorated-(GTK-WINDOW-(window)-FALSE-)-
    
  2. 自定义控件样式

    • GdkRGBA:用于设置颜色。
    • CSS Provider:通过字符串定义控件样式。
  3. 事件处理

    • on_close/min/max...:处理窗口操作逻辑。
  4. 动态调整布局

    • Packing:灵活管理控件的排列方式。

编译运行

# Ubuntu/Debian安装依赖:
sudo apt install libgtk-3-dev

#编译命令:
gcc custom_titlebar.c `pkg-config --cflags --libs-gt+-3.0` -o demo

#运行:
./demo

效果图如下:

Custom Titlebar Demo

如果需要进一步扩展功能(如拖动、双击最大化等),可以监听鼠标事件并调用相应API。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23532

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?