使用按键释放或按键时,C中的GTK:分段错误

时间:2016-03-15 23:21:54

标签: c gtk

对于上下文,我正在尝试制作一个程序来更改程式化标签文本以响应beaglebone black上的某些物理输入(例如,获取信号,如果高/低,则显示此文本)。代替那些我现在无法访问的输入,我决定使用密钥释放作为替代。

我一直将我的代码基于此combo-box tutorial,它根据组合框选择的文本更改标签文本。我已修改该代码以使用下面的代码中的程式化文本。

#include <gtk/gtk.h>

void combo_selected(GtkWidget *widget, gpointer window) {

  gchar *text = g_strjoin(NULL,"<span font='48' weight='bold' color='#DDDDDD'>",gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)),"</span>",NULL); //label text, uses pango markup
  gtk_label_set_markup(GTK_LABEL(window), text);
  g_free(text);
}

int main(int argc, char *argv[]) {

  GtkWidget *window;
  GtkWidget *hbox;
  GtkWidget *vbox;
  GtkWidget *combo;
  GtkWidget *label;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(window), "GtkComboBox");
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_container_set_border_width(GTK_CONTAINER(window), 15);
  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);

  hbox = gtk_hbox_new(FALSE, 0);
  vbox = gtk_vbox_new(FALSE, 15);

  combo = gtk_combo_box_new_text();
  gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Ubuntu");
  gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Arch");
  gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Fedora");
  gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Mint");
  gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Gentoo");
  gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Debian");

  gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 0);

  gchar *str = "<span font='48' weight='bold' color='#DDDDDD'>Not Initialized</span>"; //label text, uses pango markup
  label = gtk_label_new(NULL);
  gtk_label_set_markup(GTK_LABEL(label), str); //add pango str to label

  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);

  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
  gtk_container_add(GTK_CONTAINER(window), hbox);

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

  g_signal_connect(G_OBJECT(combo), "changed", 
        G_CALLBACK(combo_selected), (gpointer) label);

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}

这是有效的,但是当尝试使用按键释放或按键而不是组合框选项时,我会遇到分段错误。下面是进一步修改的代码(注释了一些内容)。

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

void fpcheck(GtkWidget *window, gpointer lbl) {
  gchar *text = "<span font='48' weight='bold' color='#DDDDDD'>Press index finger firmly on sensor.</span>";
  gtk_label_set_markup(GTK_LABEL(lbl), text);

  //sleep(2); //placeholder -> fp detection

  //text = "<span font='48' weight='bold' color='#DDDDDD'>Fingerprint recognized!</span>";
  //gtk_label_set_markup(GTK_LABEL(lbl), text);
  g_free(text);
}

int main(int argc, char *argv[]) {

  GtkWidget *window; //main window
  GtkWidget *align; //alignment settings
  GtkWidget *lbl; //text
  GdkColor color = {0, 0x0, 0x0, 0x0}; //window color

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL); //init window
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); //window pos on screen
  gtk_window_set_default_size(GTK_WINDOW(window), 800, 480); //window size
  //gtk_window_set_resizable(GTK_WINDOW(window), FALSE); //user cant resize
  gtk_window_set_title(GTK_WINDOW(window),"User Display"); //window title
  gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color); //set color to window
  align = gtk_alignment_new(.5,.5,0,0); //x,y alignment
  lbl = gtk_label_new(NULL); //label init

  gchar *str = "<span font='48' weight='bold' color='#DDDDDD'>Not Initialized</span>"; //label text, uses pango markup
  gtk_container_add(GTK_CONTAINER(align), lbl); //add label to alignment
  gtk_container_add(GTK_CONTAINER(window), align); //add label to window
  gtk_label_set_markup(GTK_LABEL(lbl), str); //add pango str to label

  g_signal_connect(G_OBJECT(window), "key-release-event", G_CALLBACK(fpcheck), (gpointer) lbl); //calls fpcheck to change label     

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

  gtk_widget_show_all(window); //build the window all at once

  gtk_main();

  return 0;
}

如果我在gtk_label_set_markup中注释掉g_free(text)行和fpcheck行,则没有错误,但它当然没有做任何事情。通过查看其他在线资源,我认为由于GTK_LABEL(lbl)中的第一个参数不正确而尝试访问fpcheck导致此错误,但这只是猜测而我不知道是什么我会把它放在那里。在这个例子中,它只是“Widget”,指的是组合框,我认为,因为它从所选选项中获取文本。

在那个注释中,我尝试删除该参数,现在而不是分段错误,我得到以下错误,甚至没有按下/释放。

(test:6698): GLib-GObject-WARNING **: invalid cast from 'GtkWindow' to 'GtkLabel'

(test:6698): Gtk-CRITICAL **: IA__gtk_label_set_markup: assertion 'GTK_IS_LABEL (label)' failed

我做了一些gdb回溯,但似乎没有一个特别有帮助。如果有人想要他们,我可以张贴他们。

关于我遇到的问题的任何想法? 感谢。

1 个答案:

答案 0 :(得分:0)

key-release-event处理程序具有此签名

gboolean
user_function (GtkWidget *widget,
               GdkEvent  *event,
               gpointer   user_data)

你的fpcheck()需要看起来像那样。

如果你学习了做例如这样的习惯,那么很容易找到这样的问题。 g_assert (GTK_IS_LABEL (user_data))作为每个处理程序中的第一件事,其中userdata必须始终是标签。