Gtk-WARNING **: Could not find signal handler - gtk

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();

Related

Is there a way to set the "cell-area" properties of GTKTreeViewColumn?

I am trying to achieve a vertical orientation of two (2) GtkCellRenderers in a GtkTreeViewColumn using glade or a gtk function without building the UI programmatically.
I have wired up my UI using glade and I realized that the cells in the GtkTreeViewColumn are oriented horizontally by default as seen in the documentation. However, I am unable to set the orientation to vertical both in glade and programmatically (using a gtk function) but building my UI programmatically, I am able to achieve this.
Is there a way to achieve the vertical orientation without having to build the UI programmatically? Thanks.
source.c
#include <gtk/gtk.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkBuilder *builder = gtk_builder_new_from_file("test.glade");
GtkListStore *p_list = GTK_LIST_STORE(gtk_builder_get_object(builder, "p_list"));
GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
GtkTreeView *pTreeView = GTK_TREE_VIEW(gtk_builder_get_object(builder, "p_tree_view"));
GtkTreeSelection *pTreeSelection = GTK_TREE_SELECTION(gtk_builder_get_object(builder, "p_tree_selection"));
GtkTreeViewColumn *pPicture = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "p_picture"));
GtkCellRenderer *picture = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "picture"));
GtkTreeViewColumn *pName = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "p_name"));
GtkCellRenderer *name = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "name"));
GtkCellRenderer *lastMessage = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "last_message"));
GtkTreeViewColumn *p_id = GTK_TREE_VIEW_COLUMN(gtk_builder_get_object(builder, "p_id"));
GtkCellRenderer *id = GTK_CELL_RENDERER(gtk_builder_get_object(builder, "id"));
/* Uncomment this block to view vertical orientation */
/* Programmatically setting up the vertical orientation*/
/*{
gtk_tree_view_remove_column(pTreeView, pName);
GtkCellArea *cell_area = gtk_cell_area_box_new();
gtk_orientable_set_orientation(GTK_ORIENTABLE(cell_area), GTK_ORIENTATION_VERTICAL);
GtkTreeViewColumn *column_1 = gtk_tree_view_column_new_with_area(cell_area);
gtk_tree_view_column_set_title(column_1, "Details");
gtk_tree_view_column_pack_start(column_1, name, FALSE);
gtk_tree_view_column_add_attribute(column_1, name, "text", 1);
gtk_tree_view_column_pack_start(column_1, lastMessage, FALSE);
gtk_tree_view_column_add_attribute(column_1, lastMessage, "text", 2);
gtk_tree_view_insert_column(pTreeView, column_1, 1);
gtk_tree_view_column_add_attribute(p_id, id, "text", 3);
gtk_cell_renderer_set_alignment(id, 0.0, 0.0);
}*/
GError *imageError = NULL;
/* Use any image here */
GdkPixbuf* image = gdk_pixbuf_new_from_file_at_size("test_profile_image.png", 50, 50, &imageError);
if (imageError)
{
g_warning("Could not load icon: %s\n", imageError->message);
g_error_free(imageError);
imageError = NULL;
}
GtkTreeIter iter;
for (size_t i = 0; i < 10; i++)
{
gtk_list_store_append(p_list, &iter);
gtk_list_store_set(p_list, &iter, 0, image, 1, "Firstname lastname", 2, "This is the very last message", 3, "1234567890", -1);
}
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show(window);
gtk_main();
return EXIT_SUCCESS;
}
test.glade
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<object class="GtkListStore" id="p_list">
<columns>
<!-- column-name picture -->
<column type="GdkPixbuf"/>
<!-- column-name p_name -->
<column type="gchararray"/>
<!-- column-name last_message -->
<column type="gchararray"/>
<!-- column-name p_id -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="window">
<property name="name">window</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow" id="p_scroll_window">
<property name="name">patient_scroll_window</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">False</property>
<property name="vexpand">True</property>
<property name="shadow_type">in</property>
<property name="propagate_natural_width">True</property>
<property name="propagate_natural_height">True</property>
<child>
<object class="GtkTreeView" id="p_tree_view">
<property name="name">p_tree_view</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">p_list</property>
<property name="search_column">1</property>
<property name="activate_on_single_click">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="p_tree_selection">
<property name="mode">browse</property>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="p_picture">
<property name="title" translatable="yes">Picture</property>
<child>
<object class="GtkCellRendererPixbuf" id="picture"/>
<attributes>
<attribute name="pixbuf">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="p_name">
<property name="title" translatable="yes">Name</property>
<child>
<object class="GtkCellRendererText" id="name"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText" id="last_message"/>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="p_id">
<property name="title" translatable="yes">ID</property>
<child>
<object class="GtkCellRendererText" id="id"/>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
test_profile_image.png
compile
gcc source.c -o source `pkg-config --cflags --libs gtk+-3.0`
As shown in the commented code above, that's the only way to achieve it at the moment.
The TreeViewColumn's CellArea needs to be programmatically set to a Vertical Orientation.

GTK+, C++, Windows, Binding to glade not working

Windows 10
File GTK_GladeInWindowsSample.c is compiled by the command
$ gcc GTK_GladeInWindowsSample.c -o GTK_GladeInWindowsSample -mwindows `pkg-config --cflags --libs gtk+-3.0 gmodule-2.0`
File GTK_GladeInWindowsSample.c
#include <gtk/gtk.h>
GtkWidget *win=NULL;
GtkBuilder *builder=NULL;
GError *error=NULL;
GtkButton *button=NULL;
void clicked(GtkButton *button, gpointer user_data)
{
gtk_button_set_label(button, "clicked");
}
void destroy_(GtkWidget *object, gpointer user_data)
{
gtk_main_quit();
}
int main (int argc, char *argv[])
{
gtk_init(&argc, &argv);
builder=gtk_builder_new();
if(!gtk_builder_add_from_file(builder, "GTK_GladeInWindowsSample.glade", &error))
{
return 0;
}
win=GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
button=GTK_BUTTON(gtk_builder_get_object(builder, "button1"));
gtk_widget_realize(win);
gtk_builder_connect_signals(builder, NULL);
gtk_widget_show_all(win);
g_object_unref(builder);
gtk_main();
return 0;
}
File GTK_GladeInWindowsSample.glade
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<signal name="destroy" handler="destroy_" swapped="no"/>
<child>
<placeholder/>
</child>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="margin_left">50</property>
<property name="margin_right">50</property>
<property name="margin_top">50</property>
<property name="margin_bottom">50</property>
<signal name="clicked" handler="clicked" swapped="no"/>
</object>
</child>
</object>
</interface>
When I press button, nothing happens (it should change the text to 'clicked'). destroy_ is not called either
Check the documentation on gtk_builder_connect_signals():
When compiling applications for Windows, you must declare signal
callbacks with G_MODULE_EXPORT, or they will not be put in the symbol
table. On Linux and Unices, this is not necessary; applications should
instead be compiled with the -Wl,--export-dynamic CFLAGS, and linked
against gmodule-export-2.0.
So your handler declarations need to look like
G_MODULE_EXPORT void clicked(GtkButton *button, gpointer user_data)
Alternatively call gtk_builder_add_callback_symbol() on every callback function.

Set gtk property using vala

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.

no method named `connect_activate` when using the gtk crate

I am trying to write simple GTK application in Rust, but faced with problem that I cannot add signal to menu item. There is simplified code to reproduce problem:
Glade file ("interface.glade"):
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<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="GtkMenuBar" id="menubar1">
<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">File</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="FileMenu">
<property name="label">gtk-new</property>
<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>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
Rust code ("main.rs"):
extern crate gtk;
mod example {
use gtk;
use gtk::traits::*;
use gtk::signal::Inhibit;
use gtk::widgets::{
Builder,
MenuItem
};
use gtk::Window;
pub fn main() {
gtk::init().unwrap_or_else(|_| panic!("Failed to initialize GTK."));
let builder = Builder::new_from_file("./interface.glade").unwrap();
let window: Window = builder.get_object("window1").unwrap();
window.connect_delete_event(|_, _| {
gtk::main_quit();
Inhibit(true)
});
let file_menu: MenuItem = builder.get_object("FileMenu").unwrap();
file_menu.connect_activate(|_| {
println!("Activated");
});
window.show_all();
gtk::main();
}
}
fn main() {
example::main()
}
And when I try to compile it, I get an error:
src/main.rs:24:19: 26:11 error: no method named `connect_activate` found for type `gtk::widgets::menu_item::MenuItem` in the current scope
src/main.rs:24 file_menu.connect_activate(|_| {
src/main.rs:25 println!("Activated");
src/main.rs:26 });
src/main.rs:24:19: 26:11 note: the method `connect_activate` exists but the following trait bounds were not satisfied: `gtk::widgets::menu_item::MenuItem : gtk::traits::button::ButtonTrait`
Am I doing something wrong?
Am I doing something wrong?
Yep! You aren't reading and addressing the error message:
the method connect_activate exists but the following trait bounds were not satisfied: gtk::widgets::menu_item::MenuItem : gtk::traits::button::ButtonTrait
Granted, this error message is worded in an obtuse manner. It's saying that the type MenuItem does not implement the trait ButtonTrait. To be honest, this is the first time I've see this particular wording of the error message, so I might be a bit wrong. If you check out the documentation(1) for MenuItem though, you can see that it does not implement ButtonTrait. This precludes you from calling the method.
I don't know what a suitable workaround is. I don't see any examples that use MenuItem. The 3 linked example projects don't use it either. It's entirely possible that it simply hasn't had all of the appropriate traits implemented yet. Perhaps this would be a good chance for you to get some commits into an up-and-coming project! ^_^
I also couldn't find any fallback methods or traits that would allow you to call connect directly.
(1): I wish I could link to the docs, but there are no officially-hosted versions I can find.

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