Обработчик сигнала старого окна заменяется новым обработчиком сигнала GTK +

Мое приложение с графическим интерфейсом имеет 2 окна.
Сигнал уничтожения главного окна настроен на выход из приложения с помощью gtk_main_quit,

Сигнал уничтожения другого окна устанавливается только для уничтожения этого конкретного окна с использованием метода gtk_widget_destroy,

Из главного окна мы запускаем другое окно. После запуска другого окна, когда мы нажимаем закрыть button(X) тогда другое окно успешно разрушается, но главное окно продолжает работать, пока все хорошо.

Теперь, когда мы нажимаем на закрытие главных окон button(X) он не выходит из всего приложения, а просто разрушает главное окно, и процесс продолжает выполняться.

Если я не запускаю другое окно из главного окна, то все работает нормально, и приложение успешно завершается.

Вот пример кода, который воспроизводит проблему:

#include <gtk/gtk.h>

#include <iostream>

using namespace std;

class OtherWindow {
private:
int number;

GtkWidget* window;

GtkWidget* button;

public:
OtherWindow(int num);

static void read_number(GtkWidget *widget, gpointer data);

};

OtherWindow::OtherWindow(int num)
{
number = num;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

button = gtk_button_new_with_label("Read Number");

gtk_container_add(GTK_CONTAINER(window), button);

// signal handler
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_widget_destroy), NULL);

g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(OtherWindow::read_number), this);

gtk_widget_show_all(window);

gtk_main();

}

void OtherWindow::read_number(GtkWidget *widget, gpointer data)
{
OtherWindow* other_win = static_cast<OtherWindow*>(data);
cout << other_win->number << endl;
}

class MainWindow {

private:
GtkWidget* window;

GtkWidget* button;

public:
MainWindow();

static void open_other_window(GtkWidget *widget, gpointer data);
};MainWindow::MainWindow()
{
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

button = gtk_button_new_with_label("Open Another Window");

gtk_container_add(GTK_CONTAINER(window), button);

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

g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(MainWindow::open_other_window), NULL);

gtk_widget_show_all(window);

gtk_main();
}

void MainWindow::open_other_window(GtkWidget *widget, gpointer data)
{
OtherWindow other(10);
}

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

MainWindow win;

}

Еще одно сомнение в том, что когда я пытался удалить gtk_main петля из OtherWindow конструктор, то приложение успешно завершается, но если я удаляю gtk_main цикл от OtherWindow конструктор, а затем нажмите кнопку, присутствующую в окне «Другое», чтобы получить доступ к переменной-члену, используя ссылку на указатель, и мое приложение получит ошибку сегментации.

Также я не использую gtkmm потому что у меня есть несколько ограничений, так как я должен запускать приложение на старых серверах Solaris, у которых нет компилятора, который бы поддерживал их.

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

0

Решение

Еще один вопрос, отвечающий сам на себя.
Первое, на что следует обратить внимание, это то, почему я использую два основных цикла, как отмечает @jku.
Я использовал два основных цикла, потому что ранее, используя только один цикл, мой процесс выгружал ядро, и я не сосредоточился на проверке того, что пошло не так, вместо этого я начал думать по-другому и вставил еще один основной цикл, который не требовался.

Теперь, почему это сбрасывало ядро, просто пришло мне в голову, когда я писал комментарии к своему сообщению. Это был объект, который был освобожден, чью ссылку я все еще использовал в обработчике сигналов Button в OtherWindow.
Когда я создал объект в стеке и, как только функция закончилась, объект был удален, но позже в обработчике сигналов, когда я попытался его использовать, он определенно сбросит ядро, о котором я только что узнал.

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

Итак, только несколько изменений в приведенном выше коде делают все правильно:

Сначала удалите основной цикл gtk из конструктора OtherWindow.

Затем динамически создайте объект OtherWindow, как показано ниже:

void MainWindow::open_other_window(GtkWidget *widget, gpointer data)
{
OtherWindow* other = new OtherWindow(10);
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]