Wrap already attached Widget into a GtkFrame

I’m trying to create a way in my application for users to style GTK widgets through CSS. I’ve reached the border property, and was wondering how I can create one in GTK.

Specifically, I was looking at how I can achieve this through GTK with Rust bindings.

GtkFrame seems to be what I’m looking for. (although I haven’t seen any mention of setting the border radius except through CSS, I believe it’s only possible to do so at compile time, which is a problem for me)

Since the GtkLabel I’m trying to apply a border to is already set as the child of a GtkBox, I can’t simply append() the GtkFrame instead of the GtkLabel - I have to “replace” it.

This is my current code:

if border_style != "none" {
    let frame = gtk::Frame::new(None);

    // how do I replace self with frame in self's parent? 

Maybe a GtkFrame isn’t the proper way of adding a border to a widget? I’ve also seen GtkBorder but the properties looked identical to a GtkFrame.

Summary: I’m trying to apply a (styled) border to GTK Widgets, can’t figure out how to properly do it. The widgets are already attached to a parent.


No need to add a GtkFrame for that.
GtkFrame is mostly relevant for its optional label, useful to group widgets together with a title.

If you just need to draw a border around a widget, just use CSS styles:

  • create a CSS with border and border-radius properties
  • load the CSS in a Gtk.CssProvider() and load it with Gtk.StyleContext.add_provider_for_display()
  • apply the style to your GtkLabel with label.add_css_class()

Here an example in Python:

#!/usr/bin/env python3

import sys
import gi
gi.require_version('Gdk', '4.0')
gi.require_version('Gtk', '4.0')
from gi.repository import Gdk, Gtk

THEME = """
label.red-frame {
    padding: 9px;
    border: 3px solid red;
    border-radius: 9px;

class MyAppWindow(Gtk.ApplicationWindow):
    __gtype_name__ = __qualname__
    def __init__(self, **kwargs):
        super().__init__(default_width=200, default_height=200, show_menubar=False, **kwargs)
        label = Gtk.Label.new("Hello World!")

class MyApp(Gtk.Application):
    __gtype_name__ = __qualname__
    def __init__(self, **kwargs):
        self.connect('activate', self.on_activate)
    def on_activate(self, app):
        cssp = Gtk.CssProvider()
        d = Gdk.Display.get_default()
        Gtk.StyleContext.add_provider_for_display(d, cssp, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

if __name__ == '__main__':


If you just need to draw a border around a widget, just use CSS styles

I don’t think there’s a way to load CSS into the application after it has been activated, which is the behavior I need in this case. Unless I’m mistaken and add_provider_for_display can be called anytime, or more than once, or if there’s another way of loading CSS at runtime :thinking:

I’m already loading some CSS styles at the start of the app:

fn load_css() {
    let provider = CssProvider::new();


Quoting from the original post:

[…] except through CSS, I believe it’s only possible to do so at compile time, which is a problem for me

To better explain my problem, I’m trying to load user-generated content that is fetched and then renderred into the GTK application. The user-generated content includes an HTML and CSS file, which I’m translating into GTK components.

For Label components I’m using the pango markup utility:

                let markup = &format!(
                    "<span foreground=\"{color}\" size=\"{font_size}\" line_height=\"{line_height}\" font_family=\"{font_family}\" font_weight=\"{font_weight}\" underline=\"{underline}\" underline_color=\"{underline_color}\" overline=\"{overline}\" overline_color=\"{overline_color}\" strikethrough=\"{strikethrough}\" strikethrough_color=\"{strikethrough_color}\">{}</span>",


However it doesn’t include border and padding.

If there was a way CSS could be loaded at runtime, that would most likely solve all my problems - but after searching I can’t seem to find it

Of course it’s possible to call add_provider_for_display multiple times, also at runtime :slight_smile:

What’s not allowed is to reuse the last CssProvider to load new CSS data. You must instantiate a new one.

You may have to call Gtk.StyleContext.remove_provider_for_display() with the previous CssProvider, to avoid collisions or leftovers.

That’s wonderful! I will try it out when I have time, thank you so much for the help

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.