I have searched existing questions, and the answer said change the pack type but the answer did not give details. I could add a button and change its pack type to "End", but if I try to add another child to set its pack type to "Start", I get the following error message that it needs some sort of placeholder. How do I do that? How do I add, in the example below, add another button on the left side of the header bar?
<?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>
<child>
<placeholder/>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Damn complex</property>
<property name="subtitle" translatable="yes">why</property>
<property name="show-close-button">True</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
</object>
<packing>
<property name="pack-type">end</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
PS: I could achieve that by adding children programmatically in C#, but I still have not found a way to do this within Glade.
private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow"))
{
builder.Autoconnect(this);
DeleteEvent += Window_DeleteEvent;
var btn1 = new Button() { Label = "Left"};
var btn2 = new Button() { Label = "Right" };
header1.PackStart(btn1);
header1.PackEnd(btn2);
header1.ShowAll();
}
I found a way. Change "Number of Items" to 2, and then add 2 buttons. Change each button's pack type.
I created very simple GTK+ GUI with Glade, which includes one toggle button. I want to assign action to this button. I have a problem with getting the signal handler for the button to work. After compiling and running I get this message:
Gtk-WARNING **: Could not find signal handler
'on_togglebutton1_toggled'. Did you compile with -rdynamic?
My current C code looks like this:
#include <gtk/gtk.h>
#include <stdio.h>
#include "f_back.h"
#define UI_FILE "gui.ui"
GtkWidget * create_window( void )
{
GtkWidget * window;
GtkBuilder * builder;
GError * error = NULL;
builder = gtk_builder_new();
if( !gtk_builder_add_from_file( builder, UI_FILE, & error ) )
{
g_warning( "Can't load builder file: %s", error->message );
g_error_free( error );
}
gtk_builder_connect_signals( builder, NULL );
window = GTK_WIDGET( gtk_builder_get_object( builder, "window1" ) );
g_object_unref( builder );
return window;
}
int
main( int argc, char * argv[] )
{
GtkWidget * window;
gtk_init( & argc, & argv );
okno = create_window();
gtk_widget_show( window );
gtk_main()
return 0;
}
f_back.h:
#include <gtk/gtk.h>
void on_togglebutton1_toggled( GtkToggleButton * togglebutton, gpointer user_data );
f_back.c:
#include "f_back.h"
void on_togglebutton1_toggled( GtkToggleButton * togglebutton, gpointer user_data )
{
g_print( "Toggle button pressed\n" );
}
GTK+ UI:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<property name="title" translatable="yes">Testowe</property>
<property name="window_position">center</property>
<signal name="destroy" handler="gtk_main_quit" swapped="no"/>
<child>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="row_homogeneous">True</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkImage" id="image1">
<property name="name">logo</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="yalign">0.10000000149011612</property>
<property name="pixbuf">logo_large.bmp</property>
<style>
<class name="logo"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="togglebutton1">
<property name="label" translatable="yes">LED ON/OFF</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="toggled" handler="on_togglebutton1_toggled" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<style>
<class name="grid"/>
</style>
</object>
</child>
</object>
</interface>
I've tried many options described on forums:
compiling with -rdynamic,
compiling with -export-dynamic,
compiling with -lgmodule-2.0,
adding gmodule-export-2.0 library.
adding extern "C" before function declaration,
using G_MODULE_EXPORT.
None of these solutions worked. I always get the same message.
My current Geany build commands:
g++ -Wall -c "%f" -l wiringPi pkg-config --cflags gtk+-3.0 --libs
gtk+-3.0 gmodule-export-2.0 -rdynamic -export-dynamic -lgmodule-2.0
g++ -Wall -o "%e" "%f" -l wiringPi pkg-config --cflags gtk+-3.0
--libs gtk+-3.0 gmodule-export-2.0 -rdynamic -export-dynamic -lgmodule-2.0
Does anybody knows what's wrong with my code?
try if you change the line okno = create_window();into window = create_window();
I am trying to make my first app in vala. I made a ui in glade with a headerbar, now I want the headerbar to show the window controls. I searched how to set a gtk property with vala but couldn't really find an answer. I could find the property which I needed to set but not how to set it in vala. The current code of my main application in vala now is this:
using Gtk;
public static int main(string[] args){
Gtk.init (ref args);
try{
var builder = new Builder();
builder.add_from_file ("Headerbar.ui");
builder.connect_signals (null);
var window = builder.get_object ("main_window") as Window;
var headerbar = builder.get_object ("headerbar") as Gtk.HeaderBar;
headerbar.set_show_close_button(true);
window.show_all ();
Gtk.main ();
} catch (Error e){
stderr.printf ("Kon ui niet laden: %s\n", e.message);
return 1;
}
return 0;
}
The code of my ui file is this:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkApplicationWindow" id="main_window">
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="sayhello">
<property name="label" translatable="yes">Say hello! </property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
</child>
</object>
</child>
When i compile the code it does not give any errors. But when i run the application, the window controls aren't showed in the header bar and i get the following error in the terminal:
(main:15420): Gtk-CRITICAL **: gtk_header_bar_set_show_close_button: assertion 'GTK_IS_HEADER_BAR (bar)' failed.
How can i properly set the property so that the headerbar shows the window controls.
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
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;
}
}