Struct gtk::Widget [−][src]
pub struct Widget(_);
Expand description
GtkWidget is the base class all widgets in GTK+ derive from. It manages the widget lifecycle, states and style.
Height-for-width Geometry Management # {geometry
-management}
GTK+ uses a height-for-width (and width-for-height) geometry management system. Height-for-width means that a widget can change how much vertical space it needs, depending on the amount of horizontal space that it is given (and similar for width-for-height). The most common example is a label that reflows to fill up the available width, wraps to fewer lines, and therefore needs less height.
Height-for-width geometry management is implemented in GTK+ by way of five virtual methods:
GtkWidgetClass.get_request_mode()
GtkWidgetClass.get_preferred_width()
GtkWidgetClass.get_preferred_height()
GtkWidgetClass.get_preferred_height_for_width()
GtkWidgetClass.get_preferred_width_for_height()
GtkWidgetClass.get_preferred_height_and_baseline_for_width()
There are some important things to keep in mind when implementing height-for-width and when using it in container implementations.
The geometry management system will query a widget hierarchy in
only one orientation at a time. When widgets are initially queried
for their minimum sizes it is generally done in two initial passes
in the SizeRequestMode
chosen by the toplevel.
For example, when queried in the normal
SizeRequestMode::HeightForWidth
mode:
First, the default minimum and natural width for each widget
in the interface will be computed using WidgetExt::preferred_width()
.
Because the preferred widths for each container depend on the preferred
widths of their children, this information propagates up the hierarchy,
and finally a minimum and natural width is determined for the entire
toplevel. Next, the toplevel will use the minimum width to query for the
minimum height contextual to that width using
WidgetExt::preferred_height_for_width()
, which will also be a highly
recursive operation. The minimum height for the minimum width is normally
used to set the minimum size constraint on the toplevel
(unless GtkWindowExt::set_geometry_hints()
is explicitly used instead).
After the toplevel window has initially requested its size in both
dimensions it can go on to allocate itself a reasonable size (or a size
previously specified with GtkWindowExt::set_default_size()
). During the
recursive allocation process it’s important to note that request cycles
will be recursively executed while container widgets allocate their children.
Each container widget, once allocated a size, will go on to first share the
space in one orientation among its children and then request each child’s
height for its target allocated width or its width for allocated height,
depending. In this way a Widget
will typically be requested its size
a number of times before actually being allocated a size. The size a
widget is finally allocated can of course differ from the size it has
requested. For this reason, Widget
caches a small number of results
to avoid re-querying for the same sizes in one allocation cycle.
See [GtkContainer’s geometry management section][container-geometry-management] to learn more about how height-for-width allocations are performed by container widgets.
If a widget does move content around to intelligently use up the
allocated size then it must support the request in both
GtkSizeRequestModes
even if the widget in question only
trades sizes in a single orientation.
For instance, a Label
that does height-for-width word wrapping
will not expect to have GtkWidgetClass.get_preferred_height()
called
because that call is specific to a width-for-height request. In this
case the label must return the height required for its own minimum
possible width. By following this rule any widget that handles
height-for-width or width-for-height requests will always be allocated
at least enough space to fit its own content.
Here are some examples of how a SizeRequestMode::HeightForWidth
widget
generally deals with width-for-height requests, for GtkWidgetClass.get_preferred_height()
it will do:
⚠️ The following code is in C ⚠️
static void
foo_widget_get_preferred_height (GtkWidget *widget,
gint *min_height,
gint *nat_height)
{
if (i_am_in_height_for_width_mode)
{
gint min_width, nat_width;
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
&min_width,
&nat_width);
GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width
(widget,
min_width,
min_height,
nat_height);
}
else
{
... some widgets do both. For instance, if a GtkLabel is
rotated to 90 degrees it will return the minimum and
natural height for the rotated label here.
}
}
And in GtkWidgetClass.get_preferred_width_for_height()
it will simply return
the minimum and natural width:
⚠️ The following code is in C ⚠️
static void
foo_widget_get_preferred_width_for_height (GtkWidget *widget,
gint for_height,
gint *min_width,
gint *nat_width)
{
if (i_am_in_height_for_width_mode)
{
GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget,
min_width,
nat_width);
}
else
{
... again if a widget is sometimes operating in
width-for-height mode (like a rotated GtkLabel) it can go
ahead and do its real width for height calculation here.
}
}
Often a widget needs to get its own request during size request or allocation. For example, when computing height it may need to also compute width. Or when deciding how to use an allocation, the widget may need to know its natural size. In these cases, the widget should be careful to call its virtual methods directly, like this:
⚠️ The following code is in C ⚠️
GTK_WIDGET_GET_CLASS(widget)->get_preferred_width (widget,
&min,
&natural);
It will not work to use the wrapper functions, such as
WidgetExt::preferred_width()
inside your own size request
implementation. These return a request adjusted by SizeGroup
and by the GtkWidgetClass.adjust_size_request()
virtual method. If a
widget used the wrappers inside its virtual method implementations,
then the adjustments (such as widget margins) would be applied
twice. GTK+ therefore does not allow this and will warn if you try
to do it.
Of course if you are getting the size request for
another widget, such as a child of a
container, you must use the wrapper APIs.
Otherwise, you would not properly consider widget margins,
SizeGroup
, and so forth.
Since 3.10 GTK+ also supports baseline vertical alignment of widgets. This
means that widgets are positioned such that the typographical baseline of
widgets in the same row are aligned. This happens if a widget supports baselines,
has a vertical alignment of Align::Baseline
, and is inside a container
that supports baselines and has a natural “row” that it aligns to the baseline,
or a baseline assigned to it by the grandparent.
Baseline alignment support for a widget is done by the GtkWidgetClass.get_preferred_height_and_baseline_for_width()
virtual function. It allows you to report a baseline in combination with the
minimum and natural height. If there is no baseline you can return -1 to indicate
this. The default implementation of this virtual function calls into the
GtkWidgetClass.get_preferred_height()
and GtkWidgetClass.get_preferred_height_for_width()
,
so if baselines are not supported it doesn’t need to be implemented.
If a widget ends up baseline aligned it will be allocated all the space in the parent
as if it was Align::Fill
, but the selected baseline can be found via WidgetExt::allocated_baseline()
.
If this has a value other than -1 you need to align the widget such that the baseline
appears at the position.
Style Properties
Widget
introduces “style
properties” - these are basically object properties that are stored
not on the object, but in the style object associated to the widget. Style
properties are set in [resource files][gtk3-Resource-Files].
This mechanism is used for configuring such things as the location of the
scrollbar arrows through the theme, giving theme authors more control over the
look of applications without the need to write a theme engine in C.
Use gtk_widget_class_install_style_property()
to install style properties for
a widget class, gtk_widget_class_find_style_property()
or
gtk_widget_class_list_style_properties()
to get information about existing
style properties and WidgetExt::style_get_property()
, gtk_widget_style_get()
or
gtk_widget_style_get_valist()
to obtain the value of a style property.
GtkWidget as GtkBuildable
The GtkWidget implementation of the GtkBuildable interface supports a
custom <accelerator>
element, which has attributes named ”key”, ”modifiers”
and ”signal” and allows to specify accelerators.
An example of a UI definition fragment specifying an accelerator:
⚠️ The following code is in C ⚠️
static void
foo_widget_class_init (FooWidgetClass *klass)
{
// ...
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
"/com/example/ui/foowidget.ui");
}
You will also need to call WidgetExt::init_template()
from the instance
initialization function:
⚠️ The following code is in C ⚠️
static void
foo_widget_init (FooWidget *self)
{
// ...
gtk_widget_init_template (GTK_WIDGET (self));
}
You can access widgets defined in the template using the
WidgetExt::template_child()
function, but you will typically declare
a pointer in the instance private data structure of your type using the same
name as the widget in the template definition, and call
gtk_widget_class_bind_template_child_private()
with that name, e.g.
⚠️ The following code is in C ⚠️
typedef struct {
GtkWidget *hello_button;
GtkWidget *goodbye_button;
} FooWidgetPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (FooWidget, foo_widget, GTK_TYPE_BOX)
static void
foo_widget_class_init (FooWidgetClass *klass)
{
// ...
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
"/com/example/ui/foowidget.ui");
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
FooWidget, hello_button);
gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass),
FooWidget, goodbye_button);
}
static void
foo_widget_init (FooWidget *widget)
{
}
You can also use gtk_widget_class_bind_template_callback()
to connect a signal
callback defined in the template with a function visible in the scope of the
class, e.g.
⚠️ The following code is in C ⚠️
// the signal handler has the instance and user data swapped
// because of the swapped="yes" attribute in the template XML
static void
hello_button_clicked (FooWidget *self,
GtkButton *button)
{
g_print ("Hello, world!\n");
}
static void
foo_widget_class_init (FooWidgetClass *klass)
{
// ...
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass),
"/com/example/ui/foowidget.ui");
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), hello_button_clicked);
}
This is an Abstract Base Class, you cannot instantiate it.
Implements
WidgetExt
, glib::ObjectExt
, BuildableExt
, WidgetExtManual
, BuildableExtManual
Implementations
Obtains the current default reading direction. See
set_default_direction()
.
Returns
the current default direction.
Sets the default reading direction for widgets where the
direction has not been explicitly set by WidgetExt::set_direction()
.
dir
the new default direction. This cannot be
TextDirection::None
.
Trait Implementations
This method returns an ordering between self
and other
values if one exists. Read more
This method tests less than (for self
and other
) and is used by the <
operator. Read more
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
Returns the type identifier of Self
.
Auto Trait Implementations
impl RefUnwindSafe for Widget
impl UnwindSafe for Widget
Blanket Implementations
Mutably borrows from an owned value. Read more
Upcasts an object to a superclass or interface T
. Read more
Upcasts an object to a reference of its superclass or interface T
. Read more
Tries to downcast to a subclass or interface implementor T
. Read more
Tries to downcast to a reference of its subclass or interface implementor T
. Read more
Tries to cast to an object of type T
. This handles upcasting, downcasting
and casting between interface and interface implementors. All checks are performed at
runtime, while downcast
and upcast
will do many checks at compile-time already. Read more
Tries to cast to reference to an object of type T
. This handles upcasting, downcasting
and casting between interface and interface implementors. All checks are performed at
runtime, while downcast
and upcast
will do many checks at compile-time already. Read more
Casts to T
unconditionally. Read more
Casts to &T
unconditionally. Read more
Returns true
if the object is an instance of (can be cast to) T
.
pub fn set_properties_from_value(
&self,
property_values: &[(&str, Value)]
) -> Result<(), BoolError>
pub fn set_property<'a, N, V>(
&self,
property_name: N,
value: V
) -> Result<(), BoolError> where
V: ToValue,
N: Into<&'a str>,
pub fn set_property_from_value<'a, N>(
&self,
property_name: N,
value: &Value
) -> Result<(), BoolError> where
N: Into<&'a str>,
Safety Read more
Safety Read more
Safety Read more
Safety Read more
pub fn connect_notify<F>(&self, name: Option<&str>, f: F) -> SignalHandlerId where
F: 'static + Fn(&T, &ParamSpec) + Send + Sync,
pub fn connect_notify_local<F>(
&self,
name: Option<&str>,
f: F
) -> SignalHandlerId where
F: 'static + Fn(&T, &ParamSpec),
pub unsafe fn connect_notify_unsafe<F>(
&self,
name: Option<&str>,
f: F
) -> SignalHandlerId where
F: Fn(&T, &ParamSpec),
pub fn has_property<'a, N>(&self, property_name: N, type_: Option<Type>) -> bool where
N: Into<&'a str>,
pub fn find_property<'a, N>(&self, property_name: N) -> Option<ParamSpec> where
N: Into<&'a str>,
pub fn connect<'a, N, F>(
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + Send + Sync + 'static,
N: Into<&'a str>,
Same as connect
but takes a SignalId
instead of a signal name.
pub fn connect_local<'a, N, F>(
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value> + 'static,
N: Into<&'a str>,
Same as connect_local
but takes a SignalId
instead of a signal name.
pub unsafe fn connect_unsafe<'a, N, F>(
&self,
signal_name: N,
after: bool,
callback: F
) -> Result<SignalHandlerId, BoolError> where
F: Fn(&[Value]) -> Option<Value>,
N: Into<&'a str>,
Same as connect_unsafe
but takes a SignalId
instead of a signal name.
Emit signal by signal id.
Emit signal with details by signal id.
Emit signal by it’s name.
pub fn bind_property<'a, O, N, M>(
&'a self,
source_property: N,
target: &'a O,
target_property: M
) -> BindingBuilder<'a> where
O: ObjectType,
N: Into<&'a str>,
M: Into<&'a str>,
Same as emit
but takes Value
for the arguments.
Same as emit_by_name
but takes Value
for the arguments.
Returns a SendValue
clone of self
.
impl<'a, T, C> FromValueOptional<'a> for T where
C: ValueTypeChecker<Error = ValueTypeMismatchOrNoneError>,
T: FromValue<'a, Checker = C>,