如何在GTK3中实现子控件的平滑圆角效果
GTK3中子控件平滑圆角抗锯齿实现问题
我希望实现子控件的平滑圆角,使其与主窗口的圆角匹配。由于GTK3无法直接将子控件裁剪到主窗口边框,我采用了区域裁剪,但边角呈现锯齿状。请问在GTK3中是否有带抗锯齿的实现方式?
以下是我使用的代码:
#include <QApplication> #include <QWidget> #pragma push_macro("signals") #undef signals #include <gtk/gtk.h> #include <gtk/gtkx.h> #include <cairo.h> #pragma pop_macro("signals") static void set_rounded_corners(GtkWidget *widget, double radius) { if (GdkWindow *gdk_window = gtk_widget_get_window(widget)) { int width = gtk_widget_get_allocated_width(widget); int height = gtk_widget_get_allocated_height(widget); cairo_surface_t *sfc = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(sfc); cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST); cairo_set_source_rgba(cr, 1, 1, 1, 1); cairo_move_to(cr, radius, 0); cairo_arc(cr, width - radius, radius, radius, -G_PI_2, 0); cairo_arc(cr, width - radius, height - radius, radius, 0, G_PI_2); cairo_arc(cr, radius, height - radius, radius, G_PI_2, G_PI); cairo_arc(cr, radius, radius, radius, G_PI, -G_PI_2); cairo_close_path(cr); cairo_fill(cr); cairo_surface_t *sfc_tgt = cairo_get_target(cr); cairo_surface_flush(sfc_tgt); cairo_region_t *mask = gdk_cairo_region_create_from_surface(sfc_tgt); gdk_window_shape_combine_region(gdk_window, mask, 0, 0); cairo_region_destroy(mask); cairo_destroy(cr); cairo_surface_destroy(sfc); } } static void on_size_allocate(GtkWidget *widget, GdkRectangle*, gpointer) { set_rounded_corners(widget, 8); } int main(int argc, char *argv[]) { QApplication app(argc, argv); gtk_init(&argc, &argv); GtkWidget *top_level_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_type_hint(GTK_WINDOW(top_level_window), GdkWindowTypeHint::GDK_WINDOW_TYPE_HINT_NORMAL); gtk_window_set_position(GTK_WINDOW(top_level_window), GtkWindowPosition::GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(top_level_window), 400, 300); g_signal_connect(top_level_window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_set_app_paintable(top_level_window, TRUE); GdkScreen *scr = gtk_widget_get_screen(top_level_window); if (GdkVisual *vis = gdk_screen_get_rgba_visual(scr)) gtk_widget_set_visual(top_level_window, vis); GtkWidget *header = gtk_header_bar_new(); gtk_window_set_titlebar(GTK_WINDOW(top_level_window), header); gtk_widget_destroy(header); GtkWidget *socket = gtk_socket_new(); gtk_container_add(GTK_CONTAINER(top_level_window), socket); g_signal_connect(G_OBJECT(socket), "size-allocate", G_CALLBACK(on_size_allocate), NULL); QWidget underlay; underlay.setStyleSheet("background: #ffffff;"); underlay.createWinId(); gtk_socket_add_id(GTK_SOCKET(socket), (Window)underlay.winId()); gtk_widget_show_all(top_level_window); underlay.show(); return app.exec(); }
已更新代码:补充缺失代码以支持编译。
当前效果:上边角可见撕裂边缘:
内容的提问来源于stack exchange,提问作者Helg1980
相关产品推荐
相关产品推荐

