简体   繁体   English

如何将我的无限循环与 GTK+ 集成?

[英]How to integrate my infinite loop with GTK+?

I have a Raspberry Pi3 board and I have some sensors.我有一个 Raspberry Pi3 板和一些传感器。 I wanted to make a GUI and the shortest was gtk+ and C++.我想做一个 GUI,最短的是 gtk+ 和 C++。 For example I got continuous ECG data.例如,我得到了连续的心电图数据。 That function what gave me the data is on an infinite loop.给我数据的 function 是无限循环的。 I would like to update in real time the GTK labels.我想实时更新 GTK 标签。 Could somebody solve the problem?有人可以解决问题吗? This the code:这是代码:

#include <gtk/gtk.h>
#include "eHealth.h"
#include <stdio.h>
#include <stdlib.h>
//g++ -lpthread -lrt a.cpp arduPi.o eHealth.o -o a `pkg-config gtkmm-2.4 --cflags --libs`


char c[256];
float ECG;


int i=0;
float looop(){
//here is the infinite loop
    while(1){
            ECG=eHealth.getECG();

        }
    return ECG;
}


static void button_clicked10(GtkWidget *widget, gpointer data){
    gtk_label_set_text(GTK_LABEL(data), "u clicked10");
}

static void button_clicked11(GtkWidget *widget, gpointer data){
    gtk_label_set_text(GTK_LABEL(data), "u clicked11");
}

int main(int argc, char* argv[])
{
        gtk_init(&argc, &argv);
        GtkWidget *window, *label, *button, *table, *label10;
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);

        table = gtk_table_new(8, 3, 10); //rows, columns, honogenous
        button = gtk_button_new_with_mnemonic("_Button");

        ECG=eHealth.getECG();

        sprintf(c,"%f", looop());
        //in this label I want to print the ECG data
        label = gtk_label_new(c);  ///(!!!)

        gtk_table_attach(GTK_TABLE(table), label, 0,1,0,1, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 1,2,0,1, GTK_FILL, GTK_FILL, 0,0);

        button = gtk_button_new_with_mnemonic("_Button 2");
        label = gtk_label_new("Hello World 2");
        gtk_table_attach(GTK_TABLE(table), label, 0,1,1,2, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 1,2,1,2, GTK_FILL, GTK_FILL, 0,0);

        button = gtk_button_new_with_mnemonic("_Button 3");
        label = gtk_label_new("Hello World 3");
        gtk_table_attach(GTK_TABLE(table), label, 0,1,2,3, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 1,2,2,3, GTK_FILL, GTK_FILL, 0,0);



        button = gtk_button_new_with_mnemonic("_Button 4");
        label = gtk_label_new("Hello World 4");
        gtk_table_attach(GTK_TABLE(table), label, 0,1,3,4, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 1,2,3,4, GTK_FILL, GTK_FILL, 0,0);


        button = gtk_button_new_with_mnemonic("_Button 5");
        label = gtk_label_new("Hello World 5");
        gtk_table_attach(GTK_TABLE(table), label, 2,3,0,1, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 3,4,0,1, GTK_FILL, GTK_FILL, 0,0);


        button = gtk_button_new_with_mnemonic("_Button 6");
        label = gtk_label_new("Hello World 6");
        gtk_table_attach(GTK_TABLE(table), label, 2,3,1,2, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 3,4,1,2, GTK_FILL, GTK_FILL, 0,0);


        button = gtk_button_new_with_mnemonic("_Button 7");
        label10 = gtk_label_new("Hello World 7");
        gtk_table_attach(GTK_TABLE(table), label10, 2,3,2,3, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 3,4,2,3, GTK_FILL, GTK_FILL, 0,0);
    g_signal_connect(button, "clicked", G_CALLBACK(button_clicked10), (gpointer)label10);

        button = gtk_button_new_with_mnemonic("_Button 8");
        label = gtk_label_new("Hello World 8");
        gtk_table_attach(GTK_TABLE(table), label, 2,3,3,4, GTK_FILL, GTK_FILL, 0,0);
        gtk_table_attach(GTK_TABLE(table), button, 3,4,3,4, GTK_FILL, GTK_FILL, 0,0);

        button = gtk_button_new_with_mnemonic("_Button 9");
        gtk_table_attach(GTK_TABLE(table), button, 0,4,4,5, GTK_FILL, GTK_FILL, 0,0);


        button = gtk_button_new_with_mnemonic("_Button 10");
        gtk_table_attach(GTK_TABLE(table), button, 0,4,5,6, GTK_FILL, GTK_FILL, 0,0);

        button = gtk_button_new_with_mnemonic("_Button 11");
        gtk_table_attach(GTK_TABLE(table), button, 0,4,6,7, GTK_FILL, GTK_FILL, 0,0);
        g_signal_connect(button, "clicked", G_CALLBACK(button_clicked11), (gpointer)label);
        button = gtk_button_new_with_mnemonic("_Button 10");
        gtk_table_attach(GTK_TABLE(table), button, 0,4,7,8, GTK_FILL, GTK_FILL, 0,0);
        g_signal_connect(button, "clicked", G_CALLBACK(button_clicked10), (gpointer)label);

        gtk_container_add(GTK_CONTAINER(window), table);


        gtk_widget_set_size_request(window, 500, 500);
        gtk_widget_show_all(window);


        gtk_main();


return 0;
}

GTK+ and its underlying libraries like GLib require to run their own main event loop. GTK +及其基础库(例如GLib)需要运行自己的主事件循环。 Any code of yours that alters GTK+/GLib stuff needs to then return, so that GTK+/GLib can deal with what you've asked them to do. 您的任何更改GTK + / GLib内容的代码都需要返回,以便GTK + / GLib可以处理您要求他们执行的操作。 If you block them using your own while or other loop, they can't do anything. 如果您使用自己的while或其他循环来阻止它们,则它们将无能为力。

I won't dwell on this further as it's basic stuff; 因为这是基本内容,所以我不再赘述。 see, for example: 参见,例如:

You can resolve your question by using a GLib timeout source, to run the function that updates your label, on a desired schedule. 您可以通过使用GLib超时源来解决您的问题,以按期望的时间表运行更新标签的功能。 There are g_timeout_add() , g_timeout_add_seconds() , and others documented at that page. g_timeout_add()g_timeout_add_seconds()和其他文档。

Here's a toy example: 这是一个玩具示例:

#include <gtk/gtk.h>

static gboolean
on_timeout (gpointer user_data)
{
  static unsigned f_times = 0;

  GtkLabel *label = GTK_LABEL (user_data);

  ++f_times;
  gchar *text = g_strdup_printf ("I have been updated %u times", f_times);
  gtk_label_set_label (label, text);
  g_free (text);

  return G_SOURCE_CONTINUE; /* or G_SOURCE_REMOVE when you want to stop */
}

int
main (int    argc,
      char **argv)
{
  gtk_init (&argc, &argv);

  GtkWidget *label = gtk_label_new ("not updated yet...");
  g_timeout_add (1000 /* milliseconds */, on_timeout, label);

  GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_add (GTK_CONTAINER (window), label);
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}

Some other points: 其他一些要点:

  • You don't mention which GTK+ version you're using. 您没有提及您使用的GTK +版本。 I assume 3, as 2 is too old to be using for new code. 我假设3,因为2太旧了,无法用于新代码。 In that case, note that GtkTable is deprecated in GTK+ 3 and gone in GTK+ 4; 在这种情况下,请注意在GTK + 3中不推荐使用GtkTable ,而在GTK + 4中则不再使用; you should be using GtkGrid instead. 您应该改用GtkGrid See Migrating from other containers to GtkGrid 请参阅从其他容器迁移到GtkGrid
  • Your compiler is linking against gtkmm , the official C++ bindings for GTK+, yet you have written all your code to call the C library directly. 您的编译器针对GTK +的官方C ++绑定gtkmm了链接,但是您已经编写了所有代码来直接调用C库。 That seems a bit odd. 这似乎有点奇怪。 gtkmm is great, so I can recommend it, but if you don't want it, then you should state your intent by using C and linking against GTK+. gtkmm很棒,所以我可以推荐它,但是如果您不想要它,则应该使用C并针对GTK +进行链接以表明您的意图。 But obviously, my code assumes you really want C. 但是显然,我的代码假定您确实想要C。

I achieve this using GTK2, check https://www.linuxtopia.org/online_books/gui_toolkit_guides/gtk+_gnome_application_development/sec-mainloop.html我使用 GTK2 实现了这一点,检查https://www.linuxtopia.org/online_books/gui_toolkit_guides/gtk+_gnome_application_development/sec-mainloop.html

You can use gtk_main_iteration();您可以使用 gtk_main_iteration();

#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm.h>

int main(int argc, char** argv)
{
    
   Gtk::Main kit(argc, argv);
   Gtk::Window win;
   Gtk::Frame m_Frame;
   m_Frame.set_label("Gtk::Frame Widget");
   win.add(m_Frame);
   win.set_default_size(900,600);
   win.set_title("Loop App");
   win.set_border_width(10);
   win.show_all_children();
```win.show();

  while(1){
    while (gtk_events_pending())
        gtk_main_iteration();
    /*Do your work*/
    /*Do your work 2*/
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM