compiling a simple gtk program with glade - c

i hav downloaded glade3 and i cant find any glade.h in it when i extract it so when i compile the following program
#include <stdio.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
GladeXML *xml;
GtkWidget *widget;
GtkWidget *display;
G_MODULE_EXPORT void on_displayButton_clicked(GtkButton *button,gpointer *data)
{
/* Find the Glade XML tree containing widget. */
xml = glade_get_widget_tree(GTK_WIDGET( widget ));
/* Pull the widgets out of the tree */
display= glade_xml_get_widget(xml, "displayLabel");
gtk_label_set_text(GTK_LABEL(display),"Hello World!\n gihansblog.com");
}
G_MODULE_EXPORT void on_exitButton_clicked(GtkButton *button,gpointer *data)
{
gtk_main_quit();
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
/*import glade file*/
xml = glade_xml_new("hello.glade", NULL, NULL);
/* get a widget (useful if you want to change something) */
widget = glade_xml_get_widget(xml, "mainWindow");
/* connect signal handlers */
glade_xml_signal_autoconnect(xml);
/*show widget*/
gtk_widget_show (widget);
gtk_main();
return 0;
}
i get an error saying glade.h not found,i have been working on it from past 5 hours but cant find a solution.

Have you tried by giving the full directory to your
"hello.glade" file.
Where it is in your system???
Otherwise you may have to convert your .glade file to .xml
Anyway in which Gtk version aru you in?

Related

gtk3 on macos: window does not restore from the dock

Using GTK3 on MacOS, after minimizing the window, the dock icon does not restore the window. I have to use the "Show All Windows" selection from the dock icon menu.
Does anyone have a work-around or know something to make the dock icons work?
I would be happy with some simple objective-c code that would make the dock icons work.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <getopt.h>
#include <unistd.h>
#include <gtk/gtk.h>
static void testBuildUI (void);
gboolean testMainLoop (void);
int
main (int argc, char *argv[])
{
gtk_init (&argc, NULL);
testBuildUI ();
testMainLoop ();
return 0;
}
static void
testBuildUI (void)
{
GtkWidget *window;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
assert (window != NULL);
gtk_widget_show_all (window);
}
int
testMainLoop (void)
{
while (1) {
gtk_main_iteration_do (FALSE);
while (gtk_events_pending ()) {
gtk_main_iteration_do (FALSE);
}
sleep (1);
}
return 0;
}
There is no special code or Objective-C needed if you use gtk_application_new instead of gtk_init and start your main loop with g_application_run.
The documentation states the following:
Currently, GtkApplication handles GTK+ initialization, application uniqueness, session management, provides some basic scriptability and desktop shell integration by exporting actions and menus and manages a list of toplevel windows whose life-cycle is automatically tied to the life-cycle of your application.
see https://docs.gtk.org/gtk3/class.Application.html
Self contained test program
Your code slightly adapted to the above points might look like the following:
#include <gtk/gtk.h>
#include <assert.h>
static void testBuildUI(GApplication *app, gpointer data);
int main(int argc, char *argv[]) {
printf("gtk version: %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version);
GtkApplication *app = gtk_application_new("com.example.MyApp",G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(testBuildUI), NULL);
g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return 0;
}
static void testBuildUI(GApplication *app, gpointer data) {
GtkWidget *window;
window = gtk_application_window_new(GTK_APPLICATION(app));
assert (window != NULL);
gtk_widget_show_all(GTK_WIDGET(window));
}
If you click on the dock icon of this test program, the window will restore as expected.
Alternative solution
If you want to avoid GApplication/GtkApplication, you could also use the gtk-mac-integration library instead, see https://github.com/jralls/gtk-mac-integration.
The library is rather small, only a few thousand lines of C code, so you can also easily take a look at how it works internally.
There is an important hint:
Older Gtk applications that aren't based around GApplication can be adapted to use the macOS menu bar and to integrate with the Dock using GtkOSXApplication. The Gtk API that GtkOSXApplication uses is deprecated in Gtk3 and has been removed from Gtk4. Since macOS integration is available directly in Gtk using GApplication GtkOSXIntegration will not be updated for the new menu API and is deprecated. Application maintainers are strongly encouraged to redesign their programs around GApplication, particularly before migrating to Gtk4.
see https://wiki.gnome.org/Projects/GTK/OSX/Integration
The integration is easy: after gtk_init create an application object. After setting up the window call gtkosx_application_ready with the application object.
As a side note, there is also a slightly more complex example in the src folder called test-integration.c under the Github link mentioned above that shows a more advanced menu and dock integration.
Finally, your program only minimally changed to work with the gtk-mac-integration lib:
#include <gtk/gtk.h>
#include <gtkosxapplication.h>
#include <assert.h>
static void testBuildUI(void);
static void testMainLoop(void);
static void
testBuildUI(void) {
GtkWidget *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
assert (window != NULL);
gtk_widget_show_all(window);
}
void
testMainLoop(void) {
while (1) {
gtk_main_iteration_do(FALSE);
while (gtk_events_pending()) {
gtk_main_iteration_do(FALSE);
}
sleep(1);
}
}
int
main(int argc, char *argv[]) {
printf("gtk version: %d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version);
gtk_init(&argc, &argv);
GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
testBuildUI();
gtkosx_application_ready(theApp);
testMainLoop();
g_object_unref(theApp);
return 0;
}
I installed the library using brew install gtk-mac-integration and linked the C program with libgtkmacintegration-gtk3.dylib. Also in this variant, the window is restored as expected. when you click on the dock icon of the program.

how i write a code for delete from cursor in gtk entry

how i write a code for delete from cursor in gtk entry
i write a code When I enter a text I delete it from button .
i try to delete only one character from entry cursor
i use g_signal_connect(): delete-from-cursor
but in callback (function) I do not know what to do
i use this code from source https://docs.gtk.org/gtk3/signal.Entry.delete-from-cursor.html
the function void clicked_callback(GtkEntry* entry,GtkDeleteType type,gint count,gpointer user_data)
{
the code of application :
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include<stdio.h>
void clicked_callback(GtkEntry* entry,GtkDeleteType type,gint count,gpointer user_data)
{
g_print("pressed");
}
int main(int argc, char **argv)
{
gtk_init(&argc,&argv);
GtkWidget *window;
GtkWidget *entry;
GtkWidget *grid;
GtkWidget *button;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window),200,200);
grid = gtk_grid_new();
gtk_container_add(GTK_CONTAINER(window),grid);
entry = gtk_entry_new();
gtk_widget_set_name(entry,"newname");
gtk_container_add(GTK_CONTAINER(window),entry);
gtk_grid_attach(GTK_GRID(grid), entry, 0, 0, 5, 1);
button = gtk_button_new_with_label("I");
gtk_grid_attach(GTK_GRID(grid),button, 0, 1, 1, 1);
g_signal_connect_swapped(button, "delete_from_cursor", G_CALLBACK(clicked_callback), entry);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
I found the answer. The code here will be in Python, but I'll explain the principles, so hopefully it won't be to hard to translate to C.
What you need to do first is connect a function to the button's clicked signal. In Python, it looks like this:
button = Gtk.Button.new_with_label("I")
button.connect("clicked", button_clicked_function)
In that function, you need to call the entry's delete_from_cursor() method, with GtkDeleteType of CHARS for the type argument, and a -1 for the count argument. This -1 tells it to delete 1 letter to the left of the cursor, instead of the right. Here is what this looks like in Python:
def button_clicked_function(button):
entry.do_delete_from_cursor(entry, Gtk.DeleteType.CHARS, -1)

How to get 2 textentry in gtk3

I'v been seaching google for 2 weeks now.
2 textentry in a gride.
(ex: userid, password)
Glade let me design that no problem...
For one textentry widget, it working.
I'm compiling/linking with mysql
so I would like to call functions, stored procedures
with entry1 and entry2.
Please help
thanks
:EDIT:
15:18 4 may 2019
I found a conclusive solution.
(But it's throwing seg fault)
bit of code following :
this is some kind of a transcription of the video into text (C code).
https://www.youtube.com/watch?v=_yTmW1QG3uk
obviously according to my goal really...
it's kind of working but let say you want to use the same
instance a second time, "seg fault"
I'm sure I will find the problem (gtk_main_quit) or something,
but the textentry multiples lines is solved :P
here's the code :
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <mysql/mysql.h>
GtkEntry *userid, *password;
static void Button_Pressed(GtkWidget *w, gpointer *data){
/* char *userid, *password;*/ //seg fault
/* userid[0]='\0';
password[0]='\0';*/
userid=gtk_entry_get_text(userid);
password=gtk_entry_get_text(password);
g_print("%s\n\r%s\n\r",userid, password);
}
static void CreateWindow(GtkApplication *myapp, gpointer *user_data){
GtkWidget *window;
window=gtk_application_window_new(myapp);
gtk_window_set_title(GTK_WIDGET(window), "Double Entry Solution");
gtk_window_set_default_size(GTK_WINDOW(window),400,400);
GtkWidget *vbox=gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
// userid pack
userid=gtk_entry_new();
gtk_box_pack_start(GTK_CONTAINER(vbox), userid, TRUE, TRUE,0);
gtk_widget_show(userid);
GtkWidget *hbox=gtk_hbox_new(TRUE,0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
// password pack
password=gtk_entry_new();
gtk_box_pack_start(GTK_BOX(hbox), password, TRUE, TRUE,0);
gtk_widget_show(password);
GtkWidget *submit=gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
gtk_box_pack_start(GTK_BOX(vbox), submit, TRUE, TRUE,0);
GtkWidget *button=gtk_button_new_with_label("Login");
g_signal_connect(button, "clicked", G_CALLBACK(Button_Pressed), NULL);
gtk_container_add(GTK_CONTAINER(submit), button);
gtk_widget_show(button);
gtk_widget_show_all(window);
}
int main(int argc, char** argv){
GtkApplication *doubleentry;
doubleentry=gtk_application_new("smdelectro.business.site.doubleentry", G_APPLICATION_FLAGS_NONE);
g_signal_connect(doubleentry, "activate", G_CALLBACK(CreateWindow), NULL);
g_application_run(G_APPLICATION(doubleentry), argc, argv);
g_object_unref(doubleentry);
return (EXIT_SUCCESS);
}
The code below work :
#include <gtk/gtk.h>
int main(int argc, char **argv)
{
// Init
gtk_init(&argc,&argv);
// Create widgets
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkGrid *grid = GTK_GRID(gtk_grid_new());
// Attach entries
gtk_grid_attach(grid,gtk_entry_new(),0,0,1,1);
gtk_grid_attach(grid,gtk_entry_new(),0,1,1,1);
// Add the grid in the window
gtk_container_add(GTK_CONTAINER(window),GTK_WIDGET(grid));
// Dirty way to force clean termination when window is closed
g_signal_connect(window,"delete-event",G_CALLBACK(gtk_main_quit),NULL);
// Show **everythings** (not only the window)
gtk_widget_show_all(window);
// Main loop
gtk_main();
return 0;
}
Without any source code I can't provide more help, could you post it please.
A common trap in GTK+3 is creating widget without showing them. If you replace gtk_widget_show_all with gtk_widget_show you will see a window without widgets, they are here but not displayed, because by default the visible property is set to FALSE.
finally,
creating c file with reference to xml is ONE way, it's cool, thanks Glade.
Creating pure C Gtk3 is pain... omg
xml parser to generate c code...
aw..
BRB

GTK3 : gtk_widget_destroy versus gtk_widget_hide

Here a short MCV to illustrate the problem I meet :
I call a dialog box from my main window.
I click on one of the buttons from the dialog (usual way I think)
If I click again on one button, dialog will not display again (I got a bunch of errors instead).
This doesn't happen of I use gtk_widget_hide instead.
(interfaces are designed with Glade3)
typedef struct {
GtkBuilder *builder;
gchar *stuff;
} Context;
void conDisplay(GtkWidget *g, gpointer userdata) {
GtkWidget *dlg, *parent;
Context *ctx=(Context *)userdata;
int ret=0;
g_printerr("clicked\n");
parent=GTK_WIDGET(gtk_builder_get_object(ctx->builder,(gchar *)"MCV"));
if (ctx->stuff) {
g_printerr("Already connected\n");
dlg=GTK_WIDGET(gtk_builder_get_object(ctx->builder,(gchar *)"question"));
gtk_window_set_transient_for(GTK_WINDOW(dlg),GTK_WINDOW(parent));
ret=gtk_dialog_run(dlg);
if (ret==-3) { // OK clicked
g_printerr("OK from Already connected\n");
}
else { g_printerr("Unknown\n"); }
gtk_window_set_transient_for(GTK_WINDOW(dlg),NULL);
gtk_widget_destroy(GTK_WIDGET(dlg));
} else {
dlg=GTK_WIDGET(gtk_builder_get_object(ctx->builder,(gchar *)"connect"));
gtk_window_set_transient_for(GTK_WINDOW(dlg),GTK_WINDOW(parent));
ret=gtk_dialog_run(dlg);
if (ret==-1) { // GO clicked
g_printerr("GO\n");
ctx->stuff="Hello";
}
else { g_printerr("Cancel\n"); }
gtk_window_set_transient_for(GTK_WINDOW(dlg),NULL);
gtk_widget_destroy(GTK_WIDGET(dlg));
}
}
int main(int argc, char **argv)
{
Context ctx;
GtkWidget *mainwin;
GtkWidget *btnCon;
GError *error=NULL;
/* Init GTK+ */
gtk_init(&argc,&argv);
ctx.builder=gtk_builder_new();
ctx.stuff=NULL;
// Load UI from file.
gtk_builder_add_from_file(ctx.builder,"mcv.glade",&error);
mainwin=GTK_WIDGET(gtk_builder_get_object(ctx.builder,(gchar *)"MCV"));
btnCon=GTK_WIDGET(gtk_builder_get_object(ctx.builder,(gchar *)"con"));
g_signal_connect(btnCon, "clicked", (GCallback)conDisplay, &ctx);
gtk_widget_show_all(mainwin);
gtk_main();
return 0;
}
Thanks for your help !
Best regards.
V.
From GtkBuilder:
A GtkBuilder holds a reference to all objects that it has constructed and drops these references when it is finalized. This finalization can cause the destruction of non-widget objects or widgets which are not contained in a toplevel window. For toplevel windows constructed by a builder, it is the responsibility of the user to call gtk_widget_destroy() to get rid of them and all the widgets they contain.
Since GtkDialog inherits from GtkWindow I would suggest separating mainwin and dlg GtkBuilders and gladefiles and use temporary GtkBuilder in conDisplay:
void conDisplay(GtkWidget *g, gpointer userdata) {
GtkWidget *dlg, *parent;
Context *ctx=(Context *)userdata;
GtkBuilder *builder = gtk_builder_new_from_file("dlg.glade"); //or even pass glade filename in Context
/* rest of the code */
gtk_widget_destroy(GTK_WIDGET(dlg));
g_object_unref(G_OBJECT(builder));
}

How to draw / render to a widget using the widgets Xid in GTK/Cairo in 'C'

I have a need to write a GTK application in C that does some animation using Cairo that will render into a GTK widget that exists in another running application. The idea is to do the very same thing you can do with VLC and Mplayer. For example Mplayer has the -wid option:
-wid (also see -guiwid) (X11, OpenGL and DirectX only)
This tells MPlayer to attach to an existing window. Useful to embed MPlayer in a browser (e.g. the plugger extension). This option
fills the given window completely, thus aspect scaling, panscan, etc
are no longer handled by MPlayer but must be managed by the
application that created the window.
With this Mplayer option you can create a GTK application with a GTKImage widget, get it's Xid and then play a movie in the GTK application using Mplayer with the Xid specified.
I'm trying to do the same thing except render/draw into the external window using Cairo. Anybody have suggestions or better yet a small code sample?
Take a look to the GtkSocket and GtkPlug classes.
The main program will create a GtkSocket and the XID you can pass to the other program will be returned by the function gtk_socket_get_id(). Then the other program will use it as argument to the gtk_plug_new() function. All the render will be done in children of this new GtkPlug object.
UPDATE: Well, if you want... here it is a minimal example of GtkSocket/GtkPlug. You don't say if you are using GTK+2 or GTK+3, so I'm assuming version 2.
server.c:
#include <gtk/gtk.h>
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *sck = gtk_socket_new();
gtk_container_add(GTK_CONTAINER(wnd), sck);
gtk_window_set_default_size(GTK_WINDOW(wnd), 400, 300);
gtk_widget_show_all(wnd);
GdkNativeWindow nwnd = gtk_socket_get_id(GTK_SOCKET(sck));
g_print("%lu\n", nwnd);
gtk_main();
return 0;
}
client.c:
#include <stdlib.h>
#include <gtk/gtk.h>
#include <cairo/cairo.h>
#include <math.h>
gboolean OnDraw(GtkWidget *w, GdkEvent *ev, gpointer data)
{
GtkAllocation size;
gtk_widget_get_allocation(w, &size);
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(w));
cairo_set_source_rgb(cr, 1, 0, 0);
cairo_arc(cr, size.width/2, size.height/2, size.height/2, 0, 2*M_PI);
cairo_fill(cr);
cairo_destroy(cr);
return TRUE;
}
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
GdkNativeWindow nwnd = strtoul(argv[1], NULL, 10);
GtkWidget *plug = gtk_plug_new(nwnd);
GtkWidget *canvas = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(plug), canvas);
g_signal_connect(canvas, "expose-event", (GCallback)OnDraw, NULL);
gtk_widget_show_all(plug);
gtk_main();
return 0;
}
The XID to be used is printed by the server and has to be copied/pasted as argument to the client:
$ ./server
60817441
^Z
[1]+ Stopped ./server
$ bg
$ ./client 60817441

Resources