如何从 Gtk::窗口调用派生对象的析构函数

how get destructor called for derived object from Gtk::Window

本文关键字:派生 对象 析构函数 调用 窗口 Gtk      更新时间:2023-10-16

我想从Gtk::Window派生,并希望从该对象创建一个独立的窗口。如果用户关闭该窗口,我如何才能调用派生对象的析构函数。

我想在窗口被用户破坏的那一刻关闭它。我尝试在"on_signal_delete"处理程序中执行此操作,但这会导致段错误。

目前我的代码从未调用独立窗口的析构函数!

#include <iostream>
#include <string>
#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
protected:
//Child widgets:
Gtk::Box m_VBox; 
Gtk::Label m_Label1;
std::string mytext;
public:
ExampleWindow(const std::string& text_):
m_VBox{ Gtk::ORIENTATION_VERTICAL }
,m_Label1{ text_ }
,mytext{ text_ }
{
set_title("Example");
set_border_width(10);
set_default_size(400, 200);
add(m_VBox);
m_VBox.pack_start( m_Label1 );
show_all_children();
}
virtual ~ExampleWindow()
{
// Not called for the stand alone win while closing it. How to achieve that?
std::cout << "Destructor called for " << mytext << std::endl;
}
bool on_delete_event( GdkEventAny* ) override
{
std::cout << "sig on delete called"  << mytext << std::endl;
// free( this ); // that results in segfault
return true;
}

};  

int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "some.base");
ExampleWindow window{ "First Window" };
// Create the same window as free window ( toplevel )
ExampleWindow* win2 = new ExampleWindow("Stand Alone Win");
win2->show();   // How can I desruct this window, if a user closes it?
//Shows the window and returns when it is closed.
return app->run(window);
}

编辑:正如评论中讨论为什么不可能不使用new我提供了这个更复杂的示例来表明我的真实世界应用程序必须从 gtk 中的信号处理程序创建新窗口。因此,需要按需创建对象。

可以按需创建新窗口的完整示例:

#include <iostream>
#include <string>
#include <gtkmm.h>

class ExampleWindow : public Gtk::Window
{
protected:
//Child widgets:
Gtk::Box m_VBox;
Gtk::Button m_button;
std::string mytext;
public:
ExampleWindow(const std::string& text_):
m_VBox{ Gtk::ORIENTATION_VERTICAL }
,m_button{ text_ }
,mytext{ text_ }
{
set_title("Example");
set_border_width(10);
set_default_size(400, 200);
add(m_VBox);
m_VBox.pack_start( m_button );
m_button.signal_clicked().connect(sigc::mem_fun(this,&ExampleWindow::on_clicked));
show_all_children();
}   
void on_clicked()
{   
ExampleWindow* win2 = new ExampleWindow("Stand Alone Win");
win2->show();   // How can I desruct this window, if a user closes it?
}

virtual ~ExampleWindow()
{
// Not called for the stand alone win while closing it. How to achieve that?
std::cout << "Destructor called for " << mytext << std::endl;
}
bool on_delete_event( GdkEventAny* ) override
{
std::cout << "sighandler on_delete called"  << mytext << std::endl;
//delete this; // results in segfault
return false;
}
};

int main(int argc, char *argv[])
{
auto app = Gtk::Application::create(argc, argv, "some.base");
ExampleWindow window{ "Press to create new win" };
//Shows the window and returns when it is closed.
return app->run(window);
}

问题仍然是:我可以在哪里挂接到信号处理程序以free动态创建的顶级窗口。

您可以动态分配win2但之后永远不会释放内存。

Gtk::Application::run()返回后,请拨打win2delete

delete win2;

编辑,在此答案的评论中讨论后

与其在ExampleWindow::on_clicked()中动态分配指针,显示它然后忘记它,不如拥有某种全局注册表,例如数组,您可以在需要时跟踪和销毁已创建窗口。提出如何做到这一点的设计不在原始问题的范围之内,所以我不会在这里提出更具体的建议。然后,您甚至可以避免使用动态分配,正如下面所建议的那样。