QT开发中文网

gtk 设置自定义标题栏之后边框无法相应拖拽改变大小的事件了

当你在 GTK 中设置自定义标题栏(通过 gtk_window_set_decorated(window, FALSE))后,窗口的边框和标题栏将不再具有默认的窗口管理行为,比如拖拽边缘来改变窗口大小。因此,你需要手动处理这些事件。

为了使自定义标题栏能够响应拖拽以改变窗口大小,你可以使用以下方法来实现:

  1. 捕获鼠标按下、移动和释放事件
  2. 根据鼠标移动的位置调整窗口的大小

下面是一个示例代码,展示了如何实现这一功能:

#include <gtk/gtk.h>

static gboolean is_dragging = FALSE;
static gint drag_start_x = 0;
static gint drag_start_y = 0;

static gboolean on_button_press_event(GtkWidget *widget, GdkEventButton *event) {
    if (event->button == GDK_BUTTON_PRIMARY) {
        // 记录起始位置
        is_dragging = TRUE;
        drag_start_x = event->x_root;
        drag_start_y = event->y_root;
    }
    return TRUE;  // 表示事件已处理
}

static gboolean on_motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
    if (is_dragging) {
        GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(widget));
        
        // 获取当前窗口的位置
        gint x, y;
        gtk_window_get_position(window, &x, &y);

        // 计算新的宽度和高度(简单逻辑)
        int new_width = MAX(100, gtk_widget_get_allocated_width(widget) + (event->x_root - drag_start_x));
        int new_height = MAX(100, gtk_widget_get_allocated_height(widget) + (event->y_root - drag_start_y));

        // 设置新的窗口尺寸
        gtk_window_resize(window, new_width, new_height);
        
        // 更新拖动起点
        drag_start_x = event->x_root;
        drag_start_y = event->y_root;

    }
    return TRUE;  // 表示事件已处理
}

static gboolean on_button_release_event(GtkWidget *widget, GdkEventButton *event) {
    if (event->button == GDK_BUTTON_PRIMARY) {
        is_dragging = FALSE;  // 停止拖动状态
    }
    return TRUE;  // 表示事件已处理
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "自定义标题栏");
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
    gtk_window_set_decorated(GTK_WINDOW(window), FALSE);  // 禁用默认装饰

    GtkWidget *header_bar = gtk_header_bar_new();
    
    GtkWidget *title_label = gtk_label_new("自定义标题");
    
    gtk_header_bar_pack_start(GTK_HEADER_BAR(header_bar), title_label);
    
    // 设置 HeaderBar 为窗口的标题栏
    gtk_window_set_titlebar(GTK_WINDOW(window), header_bar);

  	// 信号连接到事件处理程序 
	g_signal_connect(G_OBJECT(header_bar), "button-press-event", G_CALLBACK(on_button_press_event), NULL);
	g_signal_connect(G_OBJECT(header_bar), "motion-notify-event", G_CALLBACK(on_motion_notify_event), NULL);
	g_signal_connect(G_OBJECT(header_bar), "button-release-event", G_CALLBACK(on_button_release_event), NULL);

  	// 窗口关闭信号 
	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

	gtk_widget_show_all(window);

	gtk_main();

	return 0;
}

上述代码中主要实现了:

  1. 鼠标按下事件:记录初始位置,并设置拖动状态为真。
  2. 鼠标移动事件:在拖动时,根据鼠标的当前位置计算新大小并调整窗口大小。
  3. 鼠标释放事件:结束拖动状态。

注意事项:

  • 此代码只是一个基础示例,实际应用可能需要更复杂的逻辑,比如限制最小和最大宽高、考虑不同方向(上下左右)的调整等。
  • 在真正的应用中,还需要进行适当的边界检测,以确保用户无法将窗口缩小到负值或非常小的尺寸。


    内容由零声教学AI助手提供,问题来源于学员提问
目录导航
  • 上述代码中主要实现了:
  • 注意事项:
  • 本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
    转载请注明出处:https://qt.0voice.com/?id=12631

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

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

    联系我们

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

    微信号:3007537140

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

    关注我们
    x

    注册

    已经有帐号?