c - 在 GTK 中更新接口(interface)

标签 c user-interface gtk

我想制作一个显示时间的应用程序(最终我试图在不使用现有智能镜子 API 的情况下组装我自己的简单智能镜子)。我正在为 UI 使用 GTK3,但是我无法找到使 UI 更新时间的解决方案(我在前端或 GTK 方面没有经验,所以请耐心等待)。

我已经尝试围绕下面显示的部分 view3 代码放置循环,但是我发现一旦调用 gtk_main() 我就无法退出 gtk 主循环,以便 while 循环重新开始并调用时间函数我写。

我曾尝试使用像 gtk_main_iteration_do(gtk_false()) 这样的函数(false 这样它就不会阻塞)但我显然对这些函数了解不够,因为它不起作用。如果我将 gtk_main() 留在循环之外,显然 gtk_main() 永远不会被调用,我的应用程序窗口甚至不会打开。

我在下面的 main 中显示了相关代码,然后是我编写的 get_time_string() 函数的定义。

int
main (int   argc,
      char *argv[])
{
  // initialization and setting up window, packing widgets, etc

  // view3
  // populate buffer with time string
  // and insert into text view
  view3 = gtk_text_view_new();
  gtk_widget_set_name(view3, "view3");
  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view3));
  gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
  gtk_text_buffer_insert(buffer, &iter, get_time_string(), -1);
  gtk_text_view_set_editable(GTK_TEXT_VIEW(view3), FALSE);
  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(view3), FALSE);


  // More widget packing, setting up UI

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

get_time_string()的定义

char* get_time_string(){
  time_t time_var = time(NULL);
  struct tm *info;
  char *time_string = calloc(100, sizeof(char));
  info = localtime( &time_var );
  strftime(time_string, 100, "%I:%M %p", info);
  return time_string;
}

最佳答案

除非您真的需要或知道该做什么,否则您不应该使用主循环迭代。

诀窍是使用 g_timeout_add 或 g_idle_add 及其变体。如果您希望时间定期更新(对于分钟分辨率,您将每 60 秒更新一次),那么您可以使用 g_timeout_add_seconds。

出于说明目的,我将秒添加到您的时间字符串并每秒更新一次,使用您的 get_time_string 函数但创建一个非常简单的窗口来显示时间标签:

#include <time.h>
#include <stdlib.h>
#include <gtk/gtk.h>

char* get_time_string(){
  time_t time_var = time(NULL);
  struct tm *info;
  char *time_string = calloc(100, sizeof(char));
  info = localtime( &time_var );
  strftime(time_string, 100, "%I:%M:%S %p", info);
  return time_string;
}

gboolean update_label_time (gpointer user_data) {
   gchar *t = get_time_string();
   gtk_label_set_text(GTK_LABEL(user_data), t);
   g_free (t);
   return G_SOURCE_CONTINUE;
}

int main (int argc, char *argv[])
{
   gchar *t;
   GtkWidget *window;
   GtkWidget *label_time; 

   gtk_init(&argc, &argv);

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_default_size (GTK_WINDOW(window), 300, 200);
   t = get_time_string();
   label_time = gtk_label_new (t);
   g_free (t);

   g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
   gtk_container_add (GTK_CONTAINER(window), label_time);


   g_timeout_add_seconds(0.5, update_label_time, label_time);


   gtk_widget_show_all(window);

   gtk_main();

   return 0;
}

结果应该是一个标签每秒更新的窗口:

enter image description here

GLib 有自己的 time functions你应该使用它。

关于c - 在 GTK 中更新接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47599400/

相关文章:

c - 如何在文件创建时更新 GTK GUI?

c - 如何调试Linux内核的特定代码?

c - 需要帮助将数组结构更改为结构数组

python - Tkinter 密码系统

c - 如何使 g_idle_add/g_timeout_add 运行的函数异步工作?

Python - 如何使所有按钮每行对齐,看起来像按钮墙

c - 链接器找不到对我知道的库函数的引用

c - 使用 C 预处理器创建多个表布局

java - 如何在 Java 中组织 swing 内容(标签、按钮等)

c++ - 如何禁用 QDoubleSpinBox 中的向上/向下按钮