How do I make AdwSpinRow appear properly

Here is the code I have

Python
import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gio

class MainWindow(Adw.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.set_default_size(500, 250)
        
        self.window = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.header = Adw.HeaderBar()
        self.header.set_parent(self.window)
        self.set_content(self.window)
        self.content = Adw.PreferencesPage()
        self.content.set_parent(self.window)
        
        self.inputList = Adw.Clamp()
        self.inputList.set_parent(self.content)
        
        self.spinRow = Adw.SpinRow(halign=Gtk.Align.CENTER)
        self.spinRow.set_parent(self.inputList)
        
class MyApp(Adw.Application):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.connect('activate', self.on_activate)

    def on_activate(self, app):
        self.win = MainWindow(application=app)
        self.win.present()

app = MyApp(application_id="com.example.GtkApplication")
app.run(sys.argv)

But it looks like this
image

instead of this
image

How do I fix that?

Hi,

Don’t use set_parent(), it’s supposed to be used by custom widget implementations only.

Instead, set child widgets with appropriate APIs of the parent container:

import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gio

class MainWindow(Gtk.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.set_default_size(500, 250)
        
        self.window = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.header = Adw.HeaderBar()
        self.set_titlebar(self.header)
        self.set_child(self.window)
        self.content = Adw.PreferencesGroup()
        self.window.append(self.content)
        
        self.inputList = Adw.Clamp()
        self.content.add(self.inputList)
        
        self.spinRow = Adw.SpinRow(halign=Gtk.Align.CENTER)
        self.inputList.set_child(self.spinRow)
        
class MyApp(Adw.Application):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.connect('activate', self.on_activate)

    def on_activate(self, app):
        self.win = MainWindow(application=app)
        self.win.present()

app = MyApp(application_id="com.example.GtkApplication")
app.run(sys.argv)

Hi, Thank you for advice.
Would using set_parent() lead to any issues? Is there a reason it’s dedicated to custom widget implementation only?
Also do you know how to make an Adwaita ActionRow appear properly?

Let’s take GtkWindow as example: it can have several kind of children, like a titlebar or a window content. Using set_parent() can’t differentiate, you may end up with unexpected positioning or allocation.

Better use containers APIs to use the right child type, for example:

# Bad: how does the window differentiate title from content? result is random
header.set_parent(window)
content.set_parent(window)

# Good: use dedicated APIs
window.set_titlebar(header)
window.set_child(content)

What means “properly”? :slightly_smiling_face:

Here is how I would personally do:

import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gio

class MainWindow(Adw.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.set_default_size(500, 250)
        
        self.content = Adw.ToolbarView()
        self.content.add_top_bar(Adw.HeaderBar())
        self.set_content(self.content)
        
        self.page = Adw.PreferencesPage()
        self.content.set_content(self.page)
        self.group = Adw.PreferencesGroup()
        self.page.add(self.group)
        
        self.spinRow = Adw.SpinRow(title="My Title", subtitle="My subtitle")
        self.group.add(self.spinRow)
        
class MyApp(Adw.Application):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.connect('activate', self.on_activate)

    def on_activate(self, app):
        self.win = MainWindow(application=app)
        self.win.present()

app = MyApp(application_id="com.example.GtkApplication")
app.run(sys.argv)
1 Like