0

我正在用 C++ 和 GTK 3(只是学习它)创建一个小程序,但我遇到了麻烦。所以,我隔离了有问题的部分。

应该在单击按钮时获取条目并打印它。

这是代码:

#include <iostream>
#include <gtk/gtk.h>

using namespace std;

GtkWidget *wventana;
GtkWidget *wgrid;

//FUNCS

void ventana(string titulo, int margen)
{
    const char * tituloc = titulo.c_str();

    wventana = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position (GTK_WINDOW (wventana), GTK_WIN_POS_CENTER);
    gtk_window_set_title (GTK_WINDOW (wventana), tituloc);
    gtk_container_set_border_width(GTK_CONTAINER(wventana), margen);
}

void grid()
{
    wgrid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(wventana), wgrid);
    gtk_grid_set_row_spacing (GTK_GRID (wgrid), 10);
    gtk_grid_set_column_spacing (GTK_GRID (wgrid), 25);
}

void boton_clic (GtkEntry *wentrada, gpointer user_data)
{
    const char *nombre;
    nombre = gtk_entry_get_text(wentrada);
    cout << nombre << endl;
}

void entrada(int x, int y, int lx, int ly)
{
    GtkWidget *wentrada;
    wentrada = gtk_entry_new();
    gtk_grid_attach (GTK_GRID (wgrid), wentrada, x, y, lx, ly);
}

void boton(string texto, int x, int y, int lx, int ly)
{
    const char * wtexto = texto.c_str();

    GtkWidget *wboton;
    wboton = gtk_button_new_with_label (wtexto);
    gtk_grid_attach (GTK_GRID (wgrid), wboton, x, y, lx, ly);

    g_signal_connect (GTK_BUTTON (wboton), "clicked", G_CALLBACK (boton_clic), G_OBJECT     (wventana));
}

//MAIN

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

    ventana("ventana",10);
    grid();
    entrada(1, 1, 1, 1);
    boton("Aprietame", 1, 2, 1, 1);

    gtk_widget_show_all (wventana);
    gtk_main ();

    return 0;
}

它没有获取条目并显示以下错误消息:

(boton:6669): Gtk-CRITICAL **: gtk_entry_get_text: assertion 'GTK_IS_ENTRY (entry)' failed

谁能告诉问题是什么?而且,我怎样才能让它工作?或者在任何情况下,这样做的好选择是什么?(它必须具有分离的功能)

提前致谢。


感谢您的回答@ptomato,我尝试用您提出的更改替换为新代码:

#include <iostream>
#include <gtk/gtk.h>

using namespace std;

GtkWidget *wventana;
GtkWidget *wgrid;

//FUNCS

void ventana(string titulo, int margen)
{
    const char * tituloc = titulo.c_str();

    wventana = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position (GTK_WINDOW (wventana), GTK_WIN_POS_CENTER);
    gtk_window_set_title (GTK_WINDOW (wventana), tituloc);
    gtk_container_set_border_width(GTK_CONTAINER(wventana), margen);
}

void grid()
{
    wgrid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(wventana), wgrid);
    gtk_grid_set_row_spacing (GTK_GRID (wgrid), 10);
    gtk_grid_set_column_spacing (GTK_GRID (wgrid), 25);
}

void boton_clic (GtkButton *wboton, GtkEntry *wentrada)
{
    const char *nombre;
    nombre = gtk_entry_get_text (wentrada);
    cout << nombre << endl;
}

void entrada(int x, int y, int lx, int ly)
{
    GtkWidget *wentrada;
    wentrada = gtk_entry_new();
    gtk_grid_attach (GTK_GRID (wgrid), wentrada, x, y, lx, ly);
}

void boton(string texto, int x, int y, int lx, int ly)
{
    const char * wtexto = texto.c_str();

    GtkWidget *wboton;
    wboton = gtk_button_new_with_label (wtexto);
    gtk_grid_attach (GTK_GRID (wgrid), wboton, x, y, lx, ly);

    g_signal_connect (wboton, "clicked", G_CALLBACK (boton_clic), wentrada);
}

//MAIN

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

    ventana("ventana",10);
    grid();
    entrada(1, 1, 1, 1);
    boton("Aprietame", 1, 2, 1, 1);

    gtk_widget_show_all (wventana);
    gtk_main ();

    return 0;
}

但是当我尝试编译它时,它显示:

In file included from /usr/include/glib-2.0/gobject/gobject.h:28:0,
                 from /usr/include/glib-2.0/gobject/gbinding.h:29,
                 from /usr/include/glib-2.0/glib-object.h:23,
                 from /usr/include/glib-2.0/gio/gioenums.h:28,
                 from /usr/include/glib-2.0/gio/giotypes.h:28,
                 from /usr/include/glib-2.0/gio/gio.h:26,
                 from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
                 from /usr/include/gtk-3.0/gdk/gdk.h:32,
                 from /usr/include/gtk-3.0/gtk/gtk.h:30,
                 from boton.cpp:2:
boton.cpp: In function ‘void boton(std::string, int, int, int, int)’:
boton.cpp:51:64: error: ‘wentrada’ was not declared in this scope
  g_signal_connect (wboton, "clicked", G_CALLBACK (boton_clic), wentrada);
                                                                ^
/usr/include/glib-2.0/gobject/gsignal.h:472:73: note: in definition of macro     ‘g_signal_connect’
     g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL,     (GConnectFlags) 0)
                                                                             ^
 Compilation failed.

怎么了?我应该怎么办???

您能否再次解释一下第二个论点?(英语不是我的母语,这部分让我有点困惑:P)

再次感谢。

4

1 回答 1

2

boton_clic信号处理程序有两个参数:aGtkWidget *和指向您指定的某些用户数据的指针。第一个参数始终是发送信号的对象,因此是wboton; 但是您标记了参数wentrada并将其视为 a GtkEntry *,因此出现错误消息。

第二个参数是您在连接信号时指定的用户数据。在您的g_signal_connect()呼叫中,您经过wventana这里。但是,如果您想访问信号处理程序中的条目,则应该通过wentrada

所以,它应该是这样的:

void boton_clic (GtkButton *wboton, GtkEntry *wentrada)
{
    const char *nombre;
    nombre = gtk_entry_get_text (wentrada);
    cout << nombre << endl;
}

...

g_signal_connect (wboton, "clicked", G_CALLBACK (boton_clic), wentrada);
于 2014-08-28T15:39:50.117 回答