Why does the DrawingArea not redraw? - gtk

I have this code in vala:
using Gtk;
class Elecciones : GLib.Object {
private Gtk.Window ventana;
private Gtk.Entry partido1;
private Gtk.Entry partido2;
private Gtk.Entry partido3;
private Gtk.DrawingArea tabla;
public Elecciones(){
var builder = new Builder();
builder.add_from_file("elecciones.ui");
builder.connect_signals(null);
var ventana = builder.get_object("window1") as Window;
ventana.title = "Grafico electoral";
ventana.destroy.connect(Gtk.main_quit);
var contenedor = builder.get_object("contenedor") as Box;
var caja1 = builder.get_object("caja1") as Box;
var label1 = builder.get_object("label1") as Label;
partido1 = builder.get_object("partido1") as Entry;
var caja2 = builder.get_object("caja2") as Box;
var label2 = builder.get_object("label2") as Label;
partido2 = builder.get_object("partido2") as Entry;
var caja3 = builder.get_object("caja3") as Box;
var label3 = builder.get_object("partido3") as Label;
partido3 = builder.get_object("partido3") as Entry;
var boton = builder.get_object("boton") as Button;
var tabla = builder.get_object("tabla") as DrawingArea;
boton.clicked.connect(()=>{
int v1 = int.parse(partido1.get_text());
int v2 = int.parse(partido2.get_text());
int v3 = int.parse(partido3.get_text());
int total = v1+v2+v3;
int cuadro1 = v1*200/total;
int cuadro2 = v2*200/total;
int cuadro3 = v3*200/total;
string percent1 = (v1*100/total).to_string();
string percent2 = (v2*100/total).to_string();
string percent3 = (v3*100/total).to_string();
ventana.style_updated();
tabla.draw.connect((context)=>{
weak Gtk.StyleContext style_context = tabla.get_style_context();
int height = tabla.get_allocated_height();
int width = tabla.get_allocated_width();
context.set_source_rgba(0.144360,0.284024,0.839825,1);
context.rectangle(30, 0, cuadro1, 100);
context.fill();
context.set_source_rgba(1,1,1,1);
context.select_font_face("serif",Cairo.FontSlant.NORMAL,Cairo.FontWeight.NORMAL);
context.set_font_size(16);
context.move_to(35,30);
context.show_text(percent1+"%");
context.set_source_rgba(0.980442,0.118050,0.000000,1);
context.rectangle(30+cuadro1, 0, cuadro2, 100);
context.fill();
context.set_source_rgba(1,1,1,1);
context.select_font_face("serif",Cairo.FontSlant.NORMAL,Cairo.FontWeight.NORMAL);
context.set_font_size(16);
context.move_to(35+cuadro1,30);
context.show_text(percent2+"%");
context.set_source_rgba(0,0.980442,0.092757,1);
context.rectangle(30+cuadro1+cuadro2,0,cuadro3, 100);
context.fill();
context.set_source_rgba(1,1,1,1);
context.select_font_face("serif",Cairo.FontSlant.NORMAL,Cairo.FontWeight.NORMAL);
context.set_font_size(16);
context.move_to(35+cuadro1+cuadro2,30);
context.show_text(percent3+"%");
return true;
});
});
ventana.show_all();
}
public static int main(string[] args) {
Gtk.init(ref args);
Elecciones elecciones = new Elecciones();
Gtk.main();
return 0;
}
}
And this glade code:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.0 on Mon May 5 18:42:12 2014 -->
<interface>
<!-- interface-requires gtk+ 3.10 -->
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<property name="default_width">300</property>
<property name="default_height">400</property>
<child>
<object class="GtkBox" id="contenedor">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="caja1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">20</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">20</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Partido 1: </property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="partido1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="margin_right">120</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="caja2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">20</property>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">20</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Partido 2: </property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="partido2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="margin_right">120</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="caja3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">20</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">20</property>
<property name="hexpand">True</property>
<property name="label" translatable="yes">Partido 3: </property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="partido3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">start</property>
<property name="margin_left">10</property>
<property name="margin_right">120</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="boton">
<property name="label" translatable="yes">Graficar</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">start</property>
<property name="margin_left">20</property>
<property name="margin_top">20</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="tabla">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">20</property>
<property name="margin_bottom">20</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
When I click the Graficar button it show a bar with the percent of the 3 text entries. But the problem is that when I write new percent in any entry and click the Graficar button again, it doesn't update the bar with the new dates.

Finaly I have resolved this problem. The problem was that I was sending the signal Draw inside of button signal. Now I put the signal draw outside and put a handler(activado) that draw when click the button. This is the right code:
using Gtk;
class Elecciones : GLib.Object {
private Gtk.Window ventana;
private Gtk.Entry partido1;
private Gtk.Entry partido2;
private Gtk.Entry partido3;
private Gtk.DrawingArea tabla;
private bool activado = false;
public Elecciones(){
var builder = new Builder();
builder.add_from_file("elecciones.ui");
builder.connect_signals(null);
var ventana = builder.get_object("window1") as Window;
ventana.title = "Grafico electoral";
ventana.destroy.connect(Gtk.main_quit);
var contenedor = builder.get_object("contenedor") as Box;
var caja1 = builder.get_object("caja1") as Box;
var label1 = builder.get_object("label1") as Label;
partido1 = builder.get_object("partido1") as Entry;
var caja2 = builder.get_object("caja2") as Box;
var label2 = builder.get_object("label2") as Label;
partido2 = builder.get_object("partido2") as Entry;
var caja3 = builder.get_object("caja3") as Box;
var label3 = builder.get_object("partido3") as Label;
partido3 = builder.get_object("partido3") as Entry;
var boton = builder.get_object("boton") as Button;
var tabla = builder.get_object("tabla") as DrawingArea;
boton.clicked.connect(()=>{
activado = true;
ventana.style_updated();
});
tabla.visible = true;
tabla.draw.connect((context)=>{
if(activado==true){
weak Gtk.StyleContext style_context = tabla.get_style_context();
int height = tabla.get_allocated_height();
int width = tabla.get_allocated_width();
int v1 = int.parse(partido1.get_text());
int v2 = int.parse(partido2.get_text());
int v3 = int.parse(partido3.get_text());
int total = v1+v2+v3;
int cuadro1 = v1*200/total;
int cuadro2 = v2*200/total;
int cuadro3 = v3*200/total;
string percent1 = (v1*100/total).to_string();
string percent2 = (v2*100/total).to_string();
string percent3 = (v3*100/total).to_string();
context.set_source_rgba(0.144360,0.284024,0.839825,1);
context.rectangle(30, 0, cuadro1, 100);
context.fill();
context.set_source_rgba(1,1,1,1);
context.select_font_face("serif",Cairo.FontSlant.NORMAL,Cairo.FontWeight.NORMAL);
context.set_font_size(16);
context.move_to(35,30);
context.show_text(percent1+"%");
context.set_source_rgba(0.980442,0.118050,0.000000,1);
context.rectangle(30+cuadro1, 0, cuadro2, 100);
context.fill();
context.set_source_rgba(1,1,1,1);
context.select_font_face("serif",Cairo.FontSlant.NORMAL,Cairo.FontWeight.NORMAL);
context.set_font_size(16);
context.move_to(35+cuadro1,30);
context.show_text(percent2+"%");
context.set_source_rgba(0,0.980442,0.092757,1);
context.rectangle(30+cuadro1+cuadro2,0,cuadro3, 100);
context.fill();
context.set_source_rgba(1,1,1,1);
context.select_font_face("serif",Cairo.FontSlant.NORMAL,Cairo.FontWeight.NORMAL);
context.set_font_size(16);
context.move_to(35+cuadro1+cuadro2,30);
context.show_text(percent3+"%");
}
return true;
});
tabla.queue_draw();
ventana.show_all();
}
public static int main(string[] args) {
Gtk.init(ref args);
Elecciones elecciones = new Elecciones();
Gtk.main();
return 0;
}
}

Related

Can Glade make a GtkPopoverMenu?

I can add things like a GtkButton to GtkPopoverMenu in Glade, but how to add menu items? Is it possible in Glade, or do I have to do it programmatically?
Generated Glade code
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkWindow">
<property name="can-focus">False</property>
<property name="default-width">440</property>
<property name="default-height">250</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkMenuButton" id="menubutton1">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="focus-on-click">False</property>
<property name="receives-default">True</property>
<property name="halign">end</property>
<property name="valign">start</property>
<property name="popover">popovermenu1</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<object class="GtkPopoverMenu" id="popovermenu1">
<property name="can-focus">False</property>
<property name="relative-to">menubutton1</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</interface>
The thing I am trying to achieve:

Multiple GtkPaned within a ScrolledWindow do not increase scrollbar size

Here is a Glade file to show the problem:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkListStore" id="liststore1">
<columns>
<!-- column-name gchararray1 -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">hjkrfdtrfewyujhgnbhfsfwqrethetyghgfdagfdsaf</col>
</row>
<row>
<col id="0" translatable="yes">rtejnheth</col>
</row>
<row>
<col id="0" translatable="yes">gfedjfdgvn ry,klitloiukytrgfadedsjhfdjmkiul,ou</col>
</row>
<row>
<col id="0" translatable="yes">ulkj;.io/fsbghnjmtkuiuytgafwasSvfbghnjur6ujtergfrafd</col>
</row>
<row>
<col id="0" translatable="yes">rfetgnhyetnt</col>
</row>
<row>
<col id="0" translatable="yes">grtfhbrehgewt</col>
</row>
<row>
<col id="0" translatable="yes">hgrewtghrw</col>
</row>
<row>
<col id="0" translatable="yes">gtrewhegytht</col>
</row>
<row>
<col id="0" translatable="yes">rtgehnjtehnjythnjey</col>
</row>
<row>
<col id="0" translatable="yes">rtgejhnythjye5r</col>
</row>
<row>
<col id="0" translatable="yes">ertwhrethert</col>
</row>
<row>
<col id="0" translatable="yes">wrthergthyegrt</col>
</row>
<row>
<col id="0" translatable="yes">gfedwgrwegrft</col>
</row>
</data>
</object>
<object class="GtkWindow" id="window">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">window</property>
<property name="default_width">500</property>
<property name="default_height">400</property>
<signal name="destroy" handler="on_window_destroy" swapped="no"/>
<child>
<object class="GtkPaned" id="paned1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="position">440</property>
<property name="position_set">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">100</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkPaned" id="paned3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">100</property>
<child>
<object class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore1</property>
<property name="headers_visible">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1">
<property name="ellipsize">middle</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkPaned" id="paned4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">100</property>
<child>
<object class="GtkTreeView" id="treeview2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore1</property>
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection3"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext2">
<property name="ellipsize">middle</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkPaned" id="paned5">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow5">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">100</property>
<child>
<object class="GtkTreeView" id="treeview3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore1</property>
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection4"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn3">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext3">
<property name="ellipsize">middle</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<property name="min_content_width">100</property>
<child>
<object class="GtkTreeView" id="treeview4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore1</property>
<property name="headers_visible">False</property>
<property name="search_column">0</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection5"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn4">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext4">
<property name="ellipsize">middle</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="width_request">20</property>
<property name="height_request">20</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
More info: I am trying to make a mockup of a Miller Column file browser.
I am pretty happy with my creation, except for the problem that the scrolled window gets priority. I want the panes to have priority, so that the user can increase the width of a pane, which will in turn increase the overall width of the scrolled window.
I thought of implementing something like 'ScrolledWindow property set width', but I am not finding any information like that. Or how to detect the paned bar being maxed out.

Properly structure and highlight a GtkPopoverMenu using PyGObject

I am trying to make an example of a proper Gtk.HeaderBar with Gtk.PopoverMenus that shows how the different widgets are used. I looked at a lot of examples and code, but can't figure out, how to work the Gtk.ModelButton.
Especially this sentence makes no sense to me:
When the action is specified via the “action-name” and “action-target” properties, the role of the button (i.e. whether it is a plain, check or radio button) is determined by the type of the action and doesn't have to be explicitly specified with the “role” property.
In any case, here is my attempt to just use normal widgets in the PopoverMenu, leading to inconsistent highlighting (the whole row should be highlighted):
So my question is: How are ModelButtons subclassed, so they appear as proper PopoverMenu-widgets?
Here is the Python code:
from gi.repository import Gtk, Gio
class HeaderBarWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="HeaderBar & PopoverMenu")
self.set_border_width(10)
self.set_default_size(400, 400)
builder = Gtk.Builder()
objects = builder.add_objects_from_file("popovermenu_layout.xml", ("pom_options", ""))
pom_opt = builder.get_object("pom_options")
builder.connect_signals(self)
hb = Gtk.HeaderBar()
hb.set_show_close_button(True)
hb.props.title = "HeaderBar & PopoverMenu"
self.set_titlebar(hb)
def on_click(button, popovermenu):
"""
Toggles the respective popovermenu.
"""
if popovermenu.get_visible():
popovermenu.hide()
else:
popovermenu.show_all()
button_opt = Gtk.Button()
icon = Gio.ThemedIcon(name="format-justify-fill-symbolic")
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
button_opt.add(image)
hb.pack_end(button_opt)
pom_opt.set_relative_to(button_opt)
button_opt.connect("clicked", on_click, pom_opt)
self.add(Gtk.TextView())
def print_something(self, modelbutton, event):
print("you pressed a button")
def night_mode_switcher(self, switch, state):
Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", state)
win = HeaderBarWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
And here is the model for the PopoverMenu:
<interface>
<object class="GtkPopoverMenu" id ="pom_options">
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">10</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkModelButton" id="mb_print">
<property name="visible">True</property>
<property name="text" translatable="yes">Print</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="button-press-event" handler="print_something" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckButton" id="checkbutton1">
<property name="label" translatable="yes">checkbutton</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkSwitch" id="switch1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="state-set" handler="night_mode_switcher" swapped="no"/>
<property name="margin_start">9</property>
<property name="margin_end">9</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="mb_night">
<property name="text" translatable="yes">Night Mode</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">9</property>
<property name="margin_end">9</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
I managed to solve most of what my question was. Most importantly it seems that one has to use Gtk.Application and Gtk.ApplicationWindow. I can't say that I fully understand why, but that makes it possible to add Actions in the form of Gio.SimpleActions to the application. Gtk.Builder parses the XML of the menu, and one can simply add it tot the menu using the set_popover-method. Then for each action defined in the XML (don't forget the app.-prefix in the XML) a Gio.SimpleAction is created (without the app.-prefix as name) in the Python-code and added to the application. I got a normal button, and a checkbutton to work. Still struggling with the radiobutton, but that might be another question.
Here is the Python-code:
from gi.repository import Gio, Gtk, GLib
import sys
class MainApplication(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self,
application_id="needs.dot",
flags=Gio.ApplicationFlags.FLAGS_NONE)
#https://developer.gnome.org/gio/unstable/GApplication.html#g-application-id-is-valid
self.connect("activate", self.activate_window)
def activate_window(self, app):
"""
The activate signal of Gtk.Application passes the MainApplication class
to the window. The window is then set as a window of that class.
"""
self.window = Gtk.ApplicationWindow()
self.window.set_default_size(500, 400)
self.hb = Gtk.HeaderBar()
self.hb.set_show_close_button(True)
self.hb.props.title = "HeaderBar & PopOverMenu"
self.window.set_titlebar(self.hb)
button_settings = Gtk.MenuButton()
icon = Gio.ThemedIcon(name="format-justify-fill-symbolic")
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
button_settings.add(image)
self.hb.pack_end(button_settings)
self.builder = Gtk.Builder()
self.builder.add_from_file("popovermenu_layout.xml")
pom_options = self.builder.get_object("pom_options")
button_settings.set_popover(pom_options)
#self.builder.connect_signals(self) #Not needed because of using actions?
app.add_window(self.window)
#Connects to the action. The first part of the XML name is left away:
#<property name="action-name">app.print</property>
#becomes simply "print".
action_print = Gio.SimpleAction.new("print", None)
action_print.connect("activate", self.print_something)
app.add_action(action_print)
#app.toggle becomes -> toggle
action_toggle = Gio.SimpleAction.new_stateful("toggle", None, GLib.Variant.new_boolean(False))
action_toggle.connect("change-state", self.toggle_toggled)
app.add_action(action_toggle)
btn = Gtk.Button("Button")
self.window.add(btn)
self.window.show_all()
def print_something(self, action, variable):
print("something")
def toggle_toggled(self, action, state):
action.set_state(state)
Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", state)
def on_action_quit_activated(self, action):
self.app.quit()
if __name__ == "__main__":
"""
Creates an instance of the MainApplication class that inherits from
Gtk.Application.
"""
app = MainApplication()
app.run(sys.argv)
and the XML-file for the menu:
<interface>
<object class="GtkPopoverMenu" id ="pom_options">
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">10</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkModelButton" id="mb_print">
<property name="visible">True</property>
<property name="action-name">app.print</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">Print</property>
</object>
</child>
<child>
<object class="GtkModelButton" id="mp_toggle">
<property name="visible">True</property>
<property name="action-name">app.toggle</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">Night Mode</property>
</object>
</child>
</object>
</child>
</object>
</interface>

GTK+ 3.0 with Glade 3.10: signal handler not found, menu not showing

I've written a very simple program with Glade 3.16.1 and GTK+ 3.0 (version 3.10.8) but almost nothing works.
Signal handler gtk_main_quit is not found and the menu is not displayed.
I build the program with
gcc gtktest.c -o gtktest -Wall $(pkg-config --cflags --libs gtk+-3.0 gmodule-2.0)
Source code (gtktest.c):
#include <gtk/gtk.h>
#include <string.h>
void kleine_callback (GtkWidget *w, gpointer d)
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "Hallo, Welt!");
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
}
void quit (GtkWidget * w, gpointer d)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
GtkBuilder *builder;
GError *error = NULL;
GtkWidget *window;
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, "kaixN.glade", &error)) {
g_warning ("%s", error->message);
g_free (error);
return 1;
}
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET(gtk_builder_get_object (builder, "main_window"));
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
glade file:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="main_window">
<property name="width_request">600</property>
<property name="height_request">400</property>
<property name="can_focus">False</property>
<property name="resizable">False</property>
<child>
<object class="GtkBox" id="main_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkMenuBar" id="main_menu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkMenuItem" id="menuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Datei</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="menu_item_add">
<property name="label">gtk-add</property>
<property name="related_action"/>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menu_help">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Hilfe</property>
<property name="use_underline">True</property>
<child type="submenu">
<object class="GtkMenu" id="menu3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImageMenuItem" id="menu_item_quit">
<property name="label">gtk-quit</property>
<property name="use_action_appearance">True</property>
<property name="related_action"/>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
<signal name="select" handler="quit" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkStatusbar" id="status_bar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
Everything is so simple, I can't see what I'm doing wrong...
Thx
Kai
Fixed it. The problem was:
1: Signals weren't connected correctly to events.
2: The menu is there but I looked simply at the wrong place. I'm using Ubuntu with Unity so the menu is showing up at the top of the monitor and not at the top of the application window. This post brought my attention to the issue: https://askubuntu.com/questions/460819/ubuntu-gtk-3-10-8-not-able-to-visualize-a-menubar-made-by-glade

Gtk, custom modal dialog

I am trying to make sustom modal dialog with glade.
For this I use "dialog box" from "toplevels", set transient_for_window and modal variables properly. Then I put widgets to table all packed into dialog-vbox.
And this works OK, as expected.
But, when I need more complex GUI, like I need now, and pack into dialog-vbox scrolledwindow> viewport> aspectframe> table> and then place widgets in table this dialog becomes no more modal! After some playing I conclude that it is obvious that problems with modality starts with scrolledwindow.
Is it allowed to put such complex GUI in dialog? If yes - why my dialog lost modality with gtkscrollwindow, if no, how people do such tasks? In my case I'm trying to make modal dialog which can be connected to different projects (say reusable).
GUI:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="2.24"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkDialog" id="dialog1">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="type_hint">dialog</property>
<property name="skip_taskbar_hint">True</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button2">
<property name="label" translatable="yes">OK</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">10</property>
<property name="n_columns">2</property>
<child>
<object class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">label</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">button1</action-widget>
<action-widget response="0">button2</action-widget>
</action-widgets>
</object>
</interface>
C:
int dlgmodal(GtkWidget *mainwindow, char* fmw)
{
builder = gtk_builder_new();
gtk_builder_add_from_file(builder, "external0.glade", NULL);
dialog1 = GTK_DIALOG(gtk_builder_get_object(builder, "dialog1"));
entry1 = GTK_WIDGET(gtk_builder_get_object(builder, "entry1"));
gtk_builder_connect_signals(builder, NULL);
g_object_unref(G_OBJECT(builder));
gtk_entry_set_text(GTK_ENTRY(entry1), fmw);
gtk_window_set_modal(GTK_WINDOW(GTK_DIALOG(dialog1)), TRUE);
gtk_window_set_transient_for(GTK_WINDOW(GTK_DIALOG(dialog1)), GTK_WINDOW(mainwindow));
//
int x, y;
gdk_window_get_origin(GDK_WINDOW(GTK_WIDGET(mainwindow)->window), &x, &y);
gtk_window_move(GTK_WINDOW(dialog1), x+8, y);
//
int dlgresponse;
dlgresponse = gtk_dialog_run(GTK_DIALOG(dialog1));
gtk_widget_destroy(GTK_WIDGET(GTK_DIALOG(dialog1)));
return dlgresponse;
}