GTK +: проблемы с передачей данных в функции call_back - PullRequest
0 голосов
/ 16 ноября 2011

Я создаю программу GTK, которая выполняет следующие действия: пользователь нажимает кнопку, получает информацию с сервера, а затем создает новые кнопки, по которым пользователь может щелкнуть.Технически у меня есть сигнал в main, и в этом call_back у меня есть несколько сигналов (для каждой из созданных кнопок).

Я хотел бы передать данные этой новой кнопке, но здесь она становится неприглядной.Если я создам структуру внутри моей первой кнопки, то позже произойдет сбой в кнопках, которые сгенерированы, потому что структура локально определена в стеке, и поэтому она удаляется.

Я не могу создать глобальную переменную, поскольку каждая изсозданная кнопка нуждается в разных значениях.В основном я хотел бы передать структуру с несколькими полями, когда вызывается моя начальная кнопка (метод обратного вызова), но каждая из этих структур отличается.

Единственный способ, которым я могу думать, - это разместить его в куче., но становится немного непросто узнать, когда его освободить.

Есть ли хороший способ обойти это, пожалуйста, или я придерживаюсь неправильного выбора дизайна для GTK, если обработчик сигнала создает новый обработчик сигнала, пожалуйста??

Большое спасибо.

РЕДАКТИРОВАТЬ:

Я все еще сбой, и я очень смущен, почему.

Это код дляглавная кнопка:

struct buttonData* data = (struct buttonData*) malloc(sizeof(struct buttonData));
data->IP = strdup(newDevice.IP.c_str()); // Added strdup
data->port = atoi(newDevice.port.c_str());
g_signal_connect(G_OBJECT(deviceButton), "button_press_event", G_CALLBACK(showDeviceAndConnect), (gpointer) data);

Код сгенерированной кнопки:

static void showDeviceAndConnect(GtkWidget * deviceButton, gpointer data) {
    struct buttonData* toConnect = (struct buttonData *) data;
    fprintf(stderr, "IP: %s, PORT: %d\n", toConnect->IP, toConnect->port); //SIGSEGV
}

Я не уверен, почему.Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 16 ноября 2011

Причиной сбоя является подпись вашего обратного вызова. "button-press-event" ожидает обратного вызова с подписью gboolean foo(GtkWidget* , GdkEvent*, gpointer). Поскольку ваш обратный вызов имеет сигнатуру void foo (GtkWidget * , gpointer ), второй параметр, который вы получаете в функции обратного вызова, - это не данные gpointer, которые использовались при регистрации обратного вызова, а указатель GdkEvent. Таким образом, когда вы разыменовываете указатель GdkEvent (считая его данными, которые вы передали), вы видите сбой. Чтобы исправить эту проблему, измените static void showDeviceAndConnect(GtkWidget * deviceButton, gpointer data) на static void showDeviceAndConnect(GtkWidget * deviceButton, GdkEvent *ev, gpointer data).
В качестве альтернативы, поскольку вы используете только данные в функции showDeviceAndConnect, вы можете использовать g_signal_connect_swapped, которая будет передавать данные в качестве первого параметра; так что если вы используете g_signal_connect_swapped ваша функция static void showDeviceAndConnect(GtkWidget * deviceButton, gpointer data) может быть static void showDeviceAndConnect(gpointer data).
Надеюсь, это поможет!

1 голос
/ 16 ноября 2011

Единственный способ, которым я могу придумать, - это разместить его в куче, но становится немного непросто узнать, когда его освободить.

Это способ сделать это. Выделите структуру в куче и передайте указатель на нее в качестве данных обратного вызова. Обратите внимание, что даже если это не относится к вам, поскольку вы динамически генерируете эти кнопки, использование глобальных переменных является плохим выбором в качестве решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...