【问题标题】:How to integrate my infinite loop with GTK+?如何将我的无限循环与 GTK+ 集成?
【发布时间】:2017-11-07 10:02:38
【问题描述】:

我有一个 Raspberry Pi3 板和一些传感器。我想做一个 GUI,最短的是 gtk+ 和 C++。例如,我得到了连续的心电图数据。给我数据的那个函数是无限循环的。我想实时更新 GTK 标签。有人可以解决问题吗? 这是代码:

#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;
}

【问题讨论】:

  • 旁注:如果您将 C++ 与 gtk+ 一起使用,则最好使用 gtk+ C++ 绑定:gtkmm
  • 我在代码块中开发了这个,我检查了代码块编译参数,这就是为什么我写了一个编译命令的注释。
  • 您需要回归基础,了解 GTK+ 等 GUI 工具包如何使用事件循环。您不能使用自己的 while 循环等来阻止它们。使用 GLib 超时功能按计划更新您的标签。 @BotondDénes 奇怪的是,他们正在链接 gtkmm,但没有利用它的任何好处......
  • @underscore_d 对,没注意到。然后我更推荐使用 gtkmm API。 :)

标签: c++ gtk


【解决方案1】:

GTK+ 及其底层库(如 GLib)需要运行它们自己的主事件循环。您的任何更改 GTK+/GLib 内容的代码都需要返回,以便 GTK+/GLib 可以处理您要求他们执行的操作。如果您使用自己的while 或其他循环阻止他们,他们将无能为力。

我不会进一步讨论这个,因为它是基本的东西;参见,例如:

您可以通过使用 GLib 超时源来解决您的问题,以按照所需的时间表运行更新您的标签的函数。该页面上记录了g_timeout_add()g_timeout_add_seconds() 和其他人。

这是一个玩具示例:

#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;
}

其他几点:

  • 您没有提及您使用的是哪个 GTK+ 版本。我假设 3,因为 2 太旧而不能用于新代码。在这种情况下,请注意GtkTable 在 GTK+ 3 中已弃用,在 GTK+ 4 中已消失;你应该改用GtkGrid。见Migrating from other containers to GtkGrid
  • 您的编译器正在链接gtkmm,这是 GTK+ 的官方 C++ 绑定,但您已经编写了所有代码来直接调用 C 库。这似乎有点奇怪。 gtkmm 很棒,所以我可以推荐它,但如果您不想要它,那么您应该使用 C 并链接到 GTK+ 来说明您的意图。但很明显,我的代码假设你真的想要 C。

【讨论】:

  • 我用过 GTK+ 3。谢谢。
猜你喜欢
  • 2012-09-07
  • 1970-01-01
  • 1970-01-01
  • 2022-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-21
相关资源
最近更新 更多