C 我如何告诉GTK从外部更新应用程序? 语境与问题

C 我如何告诉GTK从外部更新应用程序? 语境与问题,c,gtk3,C,Gtk3,出于某些原因,我需要分叉代码并在两个分叉上更新一个变量。变量通过mmap存储在内存中,因此所有进程都可以访问该变量。在一个子进程上,我递增变量。如何告诉GTK应用程序从子进程刷新/更新/重画 MWE /* *从mmap中存储的变量更新GTK标签 */ #包括 #包括 #包括 #包括 静态无效激活(GtkApplication*app,gpointer localval){ GtkWidget*窗口; //按钮容器 GtkWidget*按钮\框\退出; //钮扣 GtkWidget*退出按钮; /

出于某些原因,我需要分叉代码并在两个分叉上更新一个变量。变量通过
mmap
存储在内存中,因此所有进程都可以访问该变量。在一个子进程上,我递增变量。如何告诉GTK应用程序从子进程刷新/更新/重画

MWE
/*
*从mmap中存储的变量更新GTK标签
*/
#包括
#包括
#包括
#包括
静态无效激活(GtkApplication*app,gpointer localval){
GtkWidget*窗口;
//按钮容器
GtkWidget*按钮\框\退出;
//钮扣
GtkWidget*退出按钮;
//正文
GtkWidget*文本_状态;
//定义窗口,屏幕的动态大小。
窗口=gtk_应用程序_窗口_新(应用程序);
gtk_窗口设置标题(gtk_窗口(窗口),“测试”);
gtk_窗口设置默认大小(gtk_窗口(窗口),400,300);
//定义按钮框。
按钮盒退出=gtk按钮盒新建(gtk方向水平);
//定义退出按钮,将其放入框中,将框放入窗口
退出按钮=带有“退出”标签的gtk按钮(“退出”);
gtk_容器添加(gtk_容器(按钮框退出),退出按钮);
gtk_容器添加(gtk_容器(窗口),按钮框退出);
//将信号连接到按钮
g_信号_连接_交换(退出_按钮,“点击”,g_回调(gtk_小部件_销毁),窗口);
//定义文本状态
char msg[32]={0};
//“打印”行
g_snprintf(msg,sizeof msg,“val:%d\n”,*(int*)localval);
text_status=gtk_label_new(msg);
gtk_容器添加(gtk_容器(按钮框退出),文本状态);
//激活!
g_snprintf(msg,sizeof msg,“val:%d\n”,*(int*)localval);
gtk_标签设置_文本(gtk_标签(文本状态),msg);
gtk_小部件_全部显示(窗口);
}
int main(int argc,字符**argv){
GTK应用程序*app;
智力状态;
int*VAL=mmap(NULL,sizeof(int),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);
int*ABORT=mmap(NULL,sizeof(int),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);
int-pid=fork();
如果(pid==0){
而(!*中止){
printf(“%d\n”,*VAL);
//此处的增量应反映在此PID之外。
*VAL=*VAL+1;
美国LEEP(1000000);
}
出口(0);
}否则{
app=gtk_application_new(“org.gtk.example”,G_application_FLAGS_NONE);
//传球线
g_信号连接(应用程序,“激活”,g_回调(激活),VAL);
状态=g_应用程序运行(g_应用程序(应用程序)、argc、argv);
g_object_unref(应用程序);
*中止=1;
}
*中止=1;
返回状态;
}
运行时会发生什么 当MWE运行时,终端在每次更新时都会尽职尽责地打印该值。然而,GTK窗口永远显示“val:1”。我们可以通过在
GTK\u widget\u show\u all
之前的
activate
过程中添加
usleep(3000000)
来判断GTK过程可以访问存储在mmap中的值。在此变体中,窗口将永远显示“val:4”

问题再次提出
如何使GTK窗口上的输出与终端匹配?

这是因为
激活
只调用了一次(当窗口加载/激活时),但加载后没有任何东西刷新标签,我对代码做了一些更改(使用一个全局的、非常难看但很简单的说明问题),“退出按钮”现在是一个“刷新按钮”。按下它,您将看到
VAL
中的更改

/*
 * Update GTK label from variable stored in mmap
 */

#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>

static GtkWidget *text_status;

static void refresh(GtkWidget *widget, gpointer data)
{
    (void)widget;

    char msg[32]={0};

    g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)data);
    gtk_label_set_text(GTK_LABEL(text_status), msg);
}

static void activate (GtkApplication *app, gpointer localval) {
    GtkWidget *window;
    // Button Containers
    GtkWidget *button_box_quit;
    // Buttons
    GtkWidget *refresh_button;
    // Text


    // Define Window, dynamic size for screen.
    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "test");
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);

    // Define Button Boxes.
    button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);



    // Define Exit Button, put it in a box, put box in window
    refresh_button = gtk_button_new_with_label ("Refresh");
    gtk_container_add(GTK_CONTAINER (button_box_quit), refresh_button);
    gtk_container_add(GTK_CONTAINER (window), button_box_quit);

    // Connect signals to buttons
    g_signal_connect(refresh_button, "clicked", G_CALLBACK (refresh), localval);

    // Define text status
    char msg[32]={0};
    // The "print" line
    g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
    text_status = gtk_label_new(msg);
    gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);

    //Activate!
    g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
    gtk_label_set_text(GTK_LABEL(text_status), msg);
    gtk_widget_show_all (window);
}

int main (int argc, char **argv) {
    GtkApplication *app;
    int status;

    int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    int pid = fork();

    if (pid == 0) {
        while(!*ABORT) {
            printf("%d\n", *VAL);
            // Increments here should be reflected outside this PID.
            *VAL = *VAL + 1;
            usleep(1000000);
        }
        exit(0);
    } else {
        app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
        // The passing line
        g_signal_connect (app, "activate", G_CALLBACK (activate), VAL);
        status = g_application_run (G_APPLICATION (app), argc, argv);
        g_object_unref (app);
        *ABORT = 1;
    }
    *ABORT = 1;
    return status;
}
/*
*从mmap中存储的变量更新GTK标签
*/
#包括
#包括
#包括
#包括
静态GtkWidget*文本_状态;
静态无效刷新(GtkWidget*小部件,gpointer数据)
{
(无效)小部件;
char msg[32]={0};
g_snprintf(msg,sizeof msg,“val:%d\n”,*(int*)数据);
gtk_标签设置_文本(gtk_标签(文本状态),msg);
}
静态无效激活(GtkApplication*app,gpointer localval){
GtkWidget*窗口;
//按钮容器
GtkWidget*按钮\框\退出;
//钮扣
GtkWidget*刷新按钮;
//正文
//定义窗口,屏幕的动态大小。
窗口=gtk_应用程序_窗口_新(应用程序);
gtk_窗口设置标题(gtk_窗口(窗口),“测试”);
gtk_窗口设置默认大小(gtk_窗口(窗口),400,300);
//定义按钮框。
按钮盒退出=gtk按钮盒新建(gtk方向水平);
//定义退出按钮,将其放入框中,将框放入窗口
刷新按钮=带有“刷新”标签的gtk按钮(“刷新”);
gtk_容器添加(gtk_容器(按钮框退出),刷新按钮);
gtk_容器添加(gtk_容器(窗口),按钮框退出);
//将信号连接到按钮
g_信号连接(刷新按钮,“点击”,g_回调(刷新),localval);
//定义文本状态
char msg[32]={0};
//“打印”行
g_snprintf(msg,sizeof msg,“val:%d\n”,*(int*)localval);
text_status=gtk_label_new(msg);
gtk_容器添加(gtk_容器(按钮框退出),文本状态);
//激活!
g_snprintf(msg,sizeof msg,“val:%d\n”,*(int*)localval);
gtk_标签设置_文本(gtk_标签(文本状态),msg);
gtk_小部件_全部显示(窗口);
}
int main(int argc,字符**argv){
GTK应用程序*app;
智力状态;
int*VAL=mmap(NULL,sizeof(int),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);
int*ABORT=mmap(NULL,sizeof(int),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);
int-pid=fork();
如果(pid==0){
而(!*中止){
printf(“%d\n”,*VAL);
//此处的增量应反映在此PID之外。
*VAL=*VAL+1;
美国LEEP(1000000);
}
出口(0);
}否则{
app=gtk_application_new(“org.gtk.example”,G_application_FLAGS_NONE);
//传球线
g_信号连接(应用程序,“激活”,g_回调(激活),VAL);
状态=g_应用程序运行(g_应用程序
/*
 * Update GTK label from variable stored in mmap
 */

#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>

static GtkWidget *text_status;

static void refresh(GtkWidget *widget, gpointer data)
{
    (void)widget;

    char msg[32]={0};

    g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)data);
    gtk_label_set_text(GTK_LABEL(text_status), msg);
}

static void activate (GtkApplication *app, gpointer localval) {
    GtkWidget *window;
    // Button Containers
    GtkWidget *button_box_quit;
    // Buttons
    GtkWidget *refresh_button;
    // Text


    // Define Window, dynamic size for screen.
    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "test");
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);

    // Define Button Boxes.
    button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);



    // Define Exit Button, put it in a box, put box in window
    refresh_button = gtk_button_new_with_label ("Refresh");
    gtk_container_add(GTK_CONTAINER (button_box_quit), refresh_button);
    gtk_container_add(GTK_CONTAINER (window), button_box_quit);

    // Connect signals to buttons
    g_signal_connect(refresh_button, "clicked", G_CALLBACK (refresh), localval);

    // Define text status
    char msg[32]={0};
    // The "print" line
    g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
    text_status = gtk_label_new(msg);
    gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);

    //Activate!
    g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
    gtk_label_set_text(GTK_LABEL(text_status), msg);
    gtk_widget_show_all (window);
}

int main (int argc, char **argv) {
    GtkApplication *app;
    int status;

    int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    int pid = fork();

    if (pid == 0) {
        while(!*ABORT) {
            printf("%d\n", *VAL);
            // Increments here should be reflected outside this PID.
            *VAL = *VAL + 1;
            usleep(1000000);
        }
        exit(0);
    } else {
        app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
        // The passing line
        g_signal_connect (app, "activate", G_CALLBACK (activate), VAL);
        status = g_application_run (G_APPLICATION (app), argc, argv);
        g_object_unref (app);
        *ABORT = 1;
    }
    *ABORT = 1;
    return status;
}
/*
 * Update GTK label from variable stored in mmap
 * Timeout Method
 */

#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>

static GtkWidget *text_status;

static gboolean refresh(gpointer data) {
    char msg[32]={0};

    g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)data);
    gtk_label_set_text(GTK_LABEL(text_status), msg);

    return TRUE;
}

static void activate (GtkApplication *app, gpointer localval) {
    GtkWidget *window;
    // Button Containers
    GtkWidget *button_box_quit;
    // Buttons
    GtkWidget *exit_button;

    // Define Window, dynamic size for screen.
    window = gtk_application_window_new (app);
    gtk_window_set_title (GTK_WINDOW (window), "test");
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);

    // Define Button Boxes.
    button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);

    // Define Exit Button, put it in a box, put box in window
    exit_button = gtk_button_new_with_label ("Exit");
    gtk_container_add(GTK_CONTAINER (button_box_quit), exit_button);
    gtk_container_add(GTK_CONTAINER (window), button_box_quit);

    // Connect signals to buttons
    g_signal_connect_swapped (exit_button, "clicked", G_CALLBACK (gtk_widget_destroy), window);

    // Define text status
    text_status = gtk_label_new(NULL);
    gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);

    // Define timeout
    g_timeout_add(500, G_SOURCE_FUNC(refresh), localval);

    // Activate!
    refresh(localval);
    gtk_widget_show_all (window);
}

int main (int argc, char **argv) {
    GtkApplication *app;
    int status;

    int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
    int pid = fork();

    if (pid == 0) {
        while(!*ABORT) {
            printf("%d\n", *VAL);
            // Increments here should be reflected outside this PID.
            *VAL = *VAL + 1;
            usleep(1000000);
        }
        exit(0);
    } else {
        app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
        // The passing line
        g_signal_connect (app, "activate", G_CALLBACK (activate), VAL);
        status = g_application_run (G_APPLICATION (app), argc, argv);
        g_object_unref (app);
        *ABORT = 1;
    }
    *ABORT = 1;
    return status;
}