I'm new to GTK and i'm using it to create UI in C. I've created a splash screen and i'm able to close it after specified seconds using the function g_timeout_add(100, function_to_call, NULL);. The Splash screen works great. but the problem is when in extend my program further (i.e) After closing the splash screen I want another window to be displayed automatically, it doesn't happen so. Both the windows open together. Here is my program.
gboolean function_to_call(gpointer data){
gtk_quit_main();
return(FALSE);
}
int main (int argc, char *argv[]){
GtkWidget *window, *image, *another_window;
gtk_init(&argc, &argv);
.
.
.
.
.
.
.
g_timeout_add (100, function_to_call, NULL);
gtk_main ();
/*if my program is till this, splash screen closes after 1 sec . But when i try
*to define another window from here onwards and call gtk_widget_show() and gtk_main()
*again for another_ window, window and another_window both open together and window
*doesn't close after 1 sec. */
}
Any kind of help is appreciatable.
Thank you.
Your function_to_call doesn't close your splash window here, it ends the gtk_main event loop. You don't need to end the event loop.
What you want to do instead, in your function_to_call, is hide (or destroy) your splash window and show your next window (gtk_widget_hide(),gtk_widget_show()).
I've created a splashscreen header file which is shown below..
#include <gtk/gtk.h>
/* Close the splash screen */
gboolean close_screen(gpointer data)
{
gtk_widget_destroy((GtkWidget*)data);
gtk_main_quit ();
return(FALSE);
}
int Show_Splash_Screen(char* image_name,int time,int width,int height)
{
GtkWidget *image, *window;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window, width, height);
gtk_window_set_decorated(GTK_WINDOW (window), FALSE);
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER_ALWAYS);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
image=gtk_image_new_from_file(image_name);
gtk_container_add(GTK_CONTAINER(window), image);
gtk_widget_show_all (window);
g_timeout_add (time, close_screen, window);
gtk_main ();
return 0;
}
just include this file and to show a splash screen call the function
Show_Splash_Screen("image_path",time_in_seconds,width_of_image_in_pixels,height_of_image_in_pixels);
Related
I have a task to restore window frame position on screen on program startup - so to define initial window position.
Consider the following decorated GtkWindow instance on Linux:
The window has two principal boxes: frame box and client box.
And there are two GTK functions that allow to set size and position of the window on screen:
gtk_window_move() - sets window's frame box position on screen and
gtk_window_resize - sets window's client box size.
Question:
Is there any way in GTK to define initial frame placement of the window?
On Windows I can do that by calling MoveWindow() and on MacOS NSWindow setFrame method. But on GTK... Am I asking too much?
Connect to the "realize" signal for the window (important: before calling gtk_widget_show). Then call gtk_window_move from the handler:
#include <gtk/gtk.h>
void on_window_realize(GtkWidget *widget,
gpointer user_data)
{
GtkWindow *window = GTK_WINDOW(user_data);
gtk_window_move(window, 100, 40);
}
int main(int argc, char **argv) {
GtkWidget *window = NULL;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window,
"realize",
G_CALLBACK(on_window_realize),
(gpointer)window);
g_signal_connect(window, "destroy", gtk_main_quit, NULL);
gtk_widget_show(window);
gtk_main();
return 0;
}
In gtk, I am trying to make a game that displays the creator in big letters for 3 (three) seconds before displaying the main menu. I know that nothing is wrong /w the function DisplayMainMenu. For some reason this makes it just show the Asadefa screen for ever. How can I fix?
#define NOTHING
#define EMPTYSTRING "\0"
int main(int argc, char *argv[]) {
gtk_init (&argc, &argv);
Window = gtk_window_new(0);
Box = gtk_hbox_new(00, 00);
gtk_window_set_position(GTK_WINDOW(Window), 1);
gtk_window_set_default_size(GTK_WINDOW(Window),800, 500);
gtk_window_set_title(GTK_WINDOW(Window), "Fakecraft" );
g_signal_connect(Window, "destroy", gtk_main_quit, NULL);
gtk_container_set_border_width(GTK_CONTAINER(Window),16);
char *TXT=("<span font=\"72\">ASADEFA </span>");
GtkWidget (*Label) = gtk_label_new(EMPTYSTRING);
gtk_container_add(GTK_CONTAINER(Window), Box);
gtk_container_add(GTK_CONTAINER(Box), Label);
gtk_label_set_markup(GTK_LABEL(Label), TXT);
gtk_widget_show_all(Window);
gtk_main( NOTHING NOTHING );
sleep(3);
DisplayMainMenu();
return 0;
}
Don't use sleep. GTK+ uses an event loop to react to event, so you won't reach your sleep call until gtk_main_quit has been called, which is already too late. You're supposed to use g_timout_add_seconds instead to add an event source that will call your callback after your 3 seconds. In that callback, you can call your DisplayMainMenu function.
On on GTK window there is a red close icon rendered in the title bar. Normally when you click on this, the window is closed and it's resources released.
Is there a way of intercepting the normal flow to prevent the window from being destroyed so that I can show it again later? i.e. I want to hide the window not close/destroy it.
This is what I have so far.
void destroy_window_callback(GtkWidget* widget, WebWindow_Linux* source)
{
printf("Don't destroy the window, just hide it.\n");
}
g_signal_connect(web_window, "destroy", G_CALLBACK(destroy_window_callback), this);
This is probably what you need
#include <gtk/gtk.h>
void
on_button_clicked(GtkButton *button, gpointer data)
{
GtkWidget *widget;
widget = (GtkWidget *) data;
if (widget == NULL)
return;
gtk_widget_show(widget);
return;
}
gboolean
on_widget_deleted(GtkWidget *widget, GdkEvent *event, gpointer data)
{
gtk_widget_hide(widget);
return TRUE;
}
int
main(int argc, char **argv)
{
GtkWidget *window1;
GtkWidget *window2;
GtkWidget *button;
gtk_init(&argc, &argv);
window1 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
window2 = gtk_window_new(GTK_WINDOW_TOPLEVEL);
button = gtk_button_new_with_label("Show again...");
g_signal_connect(G_OBJECT(window1),
"destroy", gtk_main_quit, NULL);
g_signal_connect(G_OBJECT(window2),
"delete-event", G_CALLBACK(on_widget_deleted), NULL);
g_signal_connect(G_OBJECT(button),
"clicked", G_CALLBACK(on_button_clicked), window2);
gtk_container_add(GTK_CONTAINER(window1), button);
gtk_widget_set_size_request(window1, 300, 100);
gtk_widget_set_size_request(window2, 300, 100);
gtk_widget_show_all(window1);
gtk_widget_show(window2);
gtk_main();
return 0;
}
We basically have three widgets, two top level windows and a button. The first window has it's "destroy" event connected to gtk_main_quit() quitting the application when the window's close button is pressed. The second window has it's "delete-event" connected to a custom function. This is the important one. As you see it returns TRUE indicating that the signal was handled and thus preventing to call the default handler and hence preventing the call to gtk_widget_destroy(). Also in it we can hide the widget if we want.
How to create gtk+ windows without title bar with resize and move properties working.
I checked gtk_window_set_decorated function, but it disable resize and move features of window. I found this answer already, but I don't think it has anything to do with it.
I tried to set resizeable true after gtk_window_set_decorated but still not working
Please check code
#include <gtk/gtk.h>
int main (int argc,
char *argv[])
{
GtkWidget *window;
/* Initialize GTK+ and all of its supporting libraries. */
gtk_init (&argc, &argv);
/* Create a new window, give it a title and display it to the user. */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Hello World");
gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
//gtk_window_set_gravity(GTK_WINDOW (window), GDK_GRAVITY_NORTH_EAST);
//gtk_window_set_deletable (GTK_WINDOW (window), FALSE);
gtk_widget_show (window);
/* Hand control over to the main loop. */
gtk_main ();
return 0;
}
So what I found to work is to remove the header with gtk_window_set_decorated set to FALSE. Then manually change the cursor and call gtk_window_begin_resize_drag() to begin a resize on mousedown.
How I implemented this was to check if the mouse was near a border on a mousemove callback and if so change the cursor with gdk_window_set_cursor().
On a mousedown event near a border I call gtk_window_begin_resize_drag() with the appropriate border.
you can use GTK_WINDOW_POPUP :
#include <gtk/gtk.h>
int main (int argc,
char *argv[])
{
GtkWidget *window;
/* Initialize GTK+ and all of its supporting libraries. */
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_show (window);
gtk_main ();
return 0;
}
You should not use GTK_WINDOW_POPUP if you only want window manager decorations turned off
for the window. Instead, use gtk_window_set_decorated (GtkWindow *window, gboolean show)
to turn off window decorations.
I am fairly new to C/C++ programming, so please excuse me if something sounds stupid to you...
I am currently working on a Visual Studio C++ 2010 project that involves opengl, glut/freeglut, and gtk+.
The OpenGL is used to take an input image, manipulate its pixels based on various parameters before calling glDrawPixels() to draw the pixels from buffer for display in a glut/freeglut window.
Now I am trying to make a UI so user can adjust the parameters and see the resulting image at runtime.
What I have so far is one GTK window that contains all of the GTK widgets, and a glut/freeglut window that houses the OpenGL image. How it works is that when the button on the UI is clicked, a new GTK thread is created to display the glut/freeglut window (that contains the OpenGL rendered image.
My question is, how do I make glut/freeglut to render updated OpenGL image and display it in the same glut/freeglut window? I am not sure if it has to do with GTK threading or it's just glut/freeglut, or both. Does anyone have any advice?
Here's the stripped down code I have:
#include<freeglut.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <gtk/gtk.h>
GtkWidget *window;
GtkWidget *vbox, *hbox;
GtkWidget *button;
gint tmp_pos;
GThread *thread;
gint progress = 0;
G_LOCK_DEFINE_STATIC(progress);
GError *error = NULL;
void display()
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glRasterPos2i(x_offset,y_offset);
glDrawPixels(x2-x1+1,y2-y1+1,GL_LUMINANCE,GL_UNSIGNED_BYTE,tmp_buf);
glFlush();
}
static gpointer runGL(gpointer data)
{
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
if(Running_Mode==0)
glutInitWindowSize(3*Test_Size,Test_Size); /* 500 x 500 pixel window */
else
glutInitWindowSize(Test_Size,Test_Size); /* 500 x 500 pixel window */
glutInitWindowPosition(600,0); /* place window top left on display */
glutCreateWindow("Simulation"); /* window title */
glutDisplayFunc(display); /* display callback invoked when window opened */
myinit(); /* set attributes */
glutMainLoop(); /* enter event loop */
return (NULL);
}
/* create a g_thread for glut window */
void GLThread()
{
thread = g_thread_create(runGL, (gpointer)button, TRUE, &error);
g_print("Thread created");
if(!thread)
{
g_print("Error: %s\n", error->message);
return(-1);
}
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
if(! g_thread_supported())
g_thread_init( NULL );
gdk_threads_init();
/* Obtain gtk's global lock */
gdk_threads_enter();
gtk_init (&argc, &argv);
/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (GTK_WIDGET (window), 200, 100);
gtk_window_set_title (GTK_WINDOW (window), "GTK Entry");
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect_swapped (window, "delete-event",
G_CALLBACK (gtk_widget_destroy),
window);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
hbox = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (vbox), hbox);
gtk_widget_show (hbox);
button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
/* call the GLThread function when the button is clicked */
g_signal_connect_swapped (button, "clicked", G_CALLBACK (GLThread), window);
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
gtk_widget_set_can_default (button, TRUE);
gtk_widget_show (button);
gtk_widget_show(window);
gtk_main();
gdk_threads_leave();
}
First things first: Free-/GLUT is not a part of OpenGL. It's a 3rd party library with a similar scope (just much more simpler) like GTK+. If you're using GTK+ you don't need GLUT. Instead you should use the GTK+ OpenGL Widget provided by GTKGlExt.
I am currently working on a Visual Studio C++ 2010 project that involves opengl, glut/freeglut, and gtk+.
Why would you want to mix GLUT and GTK+? There's absolutely no sane reason to do this. GLUT is a simple application framework (creates windows, provides the event loop), GTK+ is an application framework (creates windows, provides the event loop, has widgets).
Choose one, don't mix them.
I am not sure if it has to do with GTK threading or it's just glut/freeglut, or both. Does anyone have any advice?
The problem is, that you have two libraries fighting to do the same thing (processing user input events).