Я создаю приложение, используя gtkmm, где я создаю несколько Gtk :: Boxes, а затем отображаю их по мере необходимости на экране. Эти поля отображают виджеты Gtk :: Entry для получения информации от пользователя вместе с другими виджетами.
Моя проблема в том, что когда я пытаюсь «удалить» эти поля, они, кажется, не удаляются на самом деле, поэтому они занимают память, что приводит к сбою моего приложения. Я не уверен, почему он это делает, но мне интересно вот что: каждый раз, когда выполняется моя функция remove_widget (которая удаляет Gtk :: Box, который я хочу удалить), у меня есть оператор std :: cout, который отображает " Контейнер удален ». Каждый раз теоретически он должен удалять только элемент контейнера (Gtk :: Box). Но при каждом последующем запуске количество операторов «Контейнер удален» удваивается. Таким образом, в первый раз он отображается один раз, в следующий раз отображается дважды, затем четыре раза, затем восемь и так далее.
В любом случае, суть того, что я хочу сделать, - это добавить в окно конкретный блок, получить от него информацию, а затем уничтожить его, если я смогу добавить другой Gtk :: Box. Я не знаю, лучший ли этот метод для этого, но на данный момент я так и поступаю. В любом случае, вот код, который поможет вам понять. Что происходит, так это то, что я загружаю MainWin, который создает новое окно. Затем MainWin упаковывает в него блок Event_Controller, а Event_Controller обрабатывает другие блоки, которые я хочу отобразить для пользователя. on_new_flight_clicked () обрабатывает отображение первого блока, а on_next_clicked обрабатывает отображение остальных блоков.
class MainWin : public Gtk::Window {
public:
MainWin();
virtual ~MainWin();
protected:
// signal handler
void on_button_clicked(Glib::ustring data);
// Flight Data Object
Flight flight;
// Member widgets:
Gtk::Box main_container_box; // Holds everything in the window
Gtk::Button new_comp; // Allows the user to create a new competition
Gtk::Button go_home; // Allows the user to return to the main
screen
Event_Controller* new_event;
};
class Event_Controller : public Gtk::Box {
public:
Event_Controller(Flight& tflighto);
virtual ~Event_Controller();
protected:
Flight* flight;
Gtk::Box* container_box;
void on_new_flight_clicked();
void on_next_clicked(Glib::ustring data);
void remove_widget();
Gtk::Button next; // This will appear at every step of the create a
flight sequence, except the end, taking the user to the next step
};
void Event_Controller::on_new_flight_clicked()
{
container_box = new Gtk::Box; // Create a new container box
add(*container_box); // Add it to the box
container_box->pack_start(*Gtk::manage(new Flight_Letter(flighto)),
Gtk::PACK_EXPAND_WIDGET); // Pack the first form into the container
box
add(next); // Pack the next button outside the container box
show_all_children(); // Show everything
}
void Event_Controller::remove_widget()
{
// Remove everything from Event_Controller, this is where I think* things go wrong
remove(*container_box);
delete container_box;
container_box = nullptr;
cout << "Container Removed..." << endl;
remove(next);
container_box = new Gtk::Box; // Create the container box
add(*container_box);
}
void Event_Controller::on_next_clicked(Glib::ustring data)
{
int figures_loop = 0;
// This will show the Flight_Number form. Here is the general model
for what we do in this function. This function
// gets passed an argument, and that allows us to remove the form we
need to and bring up a new form.
if (data == "first")
{
// First we remove the previous form and the container
remove_widget();
// Then we set next to send a message to this function when it's
clicked, so that it knows what form to bring up next
next.signal_clicked().connect(sigc::bind<Glib::ustring>
(sigc::mem_fun(*this, &Event_Controller::on_next_clicked), "first"));
// Create the new form
container_box->pack_start(*Gtk::manage(new
Figure_Number(num_of_figures)), Gtk::PACK_EXPAND_WIDGET);
// Pack the next button
pack_start(next);
// Show all the widgets
show_all_children();
}
// There is more to this function, I just left it out for brevity sake
}
Заранее благодарим за любую помощь, и если что-то неясно или у вас есть предложения / проблемы / комментарии, не стесняйтесь комментировать дальше.
хуже: это не MCVE, поэтому читатели, которые в противном случае могут захотеть собрать и проанализировать, чтобы помочь, не смогут. Также далеко не ясно, как вы измерили утечку, ее величину и т. д. В любом случае, у вас нет Gtk::manage()container_box, поэтому утечка произойдет при уничтожении Event_Controller. Это кажется очень неправильным. (Как только вы это исправите, обратите внимание, что вам делать все еще нужно delete после remove, так как gtkmm заменяет ссылку в Container.remove(). Тогда вы можете просто delete и позволить этому remove.) Лично я бы просто container->box.foreach() и delete его потомков. Тогда это может быть значение члена, а не указатель





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