NonSense
NonSense

Reputation: 173

Linux, C, Gtk. Close window after some time

Was trying to code. C, Linux. User enter some string and date. If it's today, then program should show a window with his string. Then this window should be closed by code, not user. And then it will pop up again after a short period of time. gtk_widget_destroy and gtk_widget_hide don't work.

`(aa:26429): Gtk-CRITICAL **: IA__gtk_widget_hide: assertion 'GTK_IS_WIDGET (widget)'   failed`


#include <gtk/gtk.h> 
#include <stdio.h> 
#include <string.h> 
#include <time.h> 
#include <unistd.h>

/* numbered markers placed below by msw for reference */    

char str[50];
int main( int argc, char *argv[] ) 
{
    printf("Enter your string\n>:");
    fgets( str, 50, stdin );

    char time_buf[10], date[10];
    int a=strlen(time_buf);
    int i=0;
    time_t endwait;
    time_t start = time(NULL);
    time_t seconds = 30;
    endwait=start+seconds;

    printf("Enter date\n>:");
    fgets(date, 10, stdin);
    time_t now;
    time(&now);
    strftime(time_buf, 21, "%Y-%m-%d", gmtime(&now));

    if (strncmp(time_buf,date,9) == 0) {
        printf("TODAY!\n");
        while (start < endwait) {
            GtkWidget *label;
            GtkWidget *window;
            gtk_init( &argc, &argv );
            window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
            gtk_window_set_title( GTK_WINDOW( window ),"ALARM");
            label = gtk_label_new( str );
            gtk_container_set_border_width(GTK_CONTAINER(window), 50);
            gtk_container_add( GTK_CONTAINER( window ), label );
            gtk_widget_show_all( window );
            g_signal_connect(G_OBJECT(window),"destroy", 
                             G_CALLBACK( gtk_main_quit ),NULL)

            gtk_main();                 // mark 1 ###
            gtk_widget_destroy (label); // mark 2 ###
          //gtk_widget_hide(window);
            start = time(NULL);
            sleep(10);
        }
    } else {
        printf("NOT TODAY");
        return 0;
    }
 }

Upvotes: 0

Views: 945

Answers (2)

msw
msw

Reputation: 43527

The big problem is that after you invoke gtk_main() at mark 1, your program does not get to run again until gtk_main exits. Prior to gtk_main returning, all widgets from the toplevel down will be destroyed. That's why I assume the error happened at mark 2 where you try to destroy a label that's already been destroyed.

It is still not clear to me why you'd want the behavior. Screen-wide popup notification behaves differently than gtk/glib/X11 programs because it is different. If I am running a program and a top-level window comes to the screen I should know what caused it and be able to get rid of it. It is more intuitive for the user if you scrap the popup, put a label below the entry¹ and change its text to "" when you want it to be invisible. And what @BasileStarynkevitch said.

¹What entry? The one that you should have to enter the string in. it would be an odd program that takes input from the console and displays output in a window.

Upvotes: 1

GTK has an event loop, started with gtk_main. Actually, it is wrapping a glib event loop, to which you can add timeouts using g_timeout_add_full (or simply g_timeout_add). This is the good way to handle your issue (make some GTK signal handler register a Glib timeout which could e.g. call gtk_widget_hide or gtk_exit ...)

Upvotes: 2

Related Questions