我遇到了用C++編寫GUI的基本問題。C++是否符合以及如何從信號中刪除小部件
當一個按鈕被點擊時,它應該刪除它的父框架,所以它自己。 但是,當按鈕被刪除時,信號/插槽機制明顯導致分段錯誤。
當不使用信號時,下面的代碼模擬類似的行爲。 a與子b一起創建。 b被要求刪除(類似於點擊按鈕)。
這個編譯和運行沒有valgrind的任何錯誤。
頭.H
class B;
class A {
private:
B* fB;
public:
A();
B* GetB() {return fB;}
void DeleteB();
};
class B {
private:
A* parent;
public:
B(A* a) {parent = a;}
void DeleteMyself();
};
實施
#include <iostream>
#include "test_delete.h"
A::A() {
std::cout << "Constructor A" << std::endl;
fB = new B(this);
}
void A::DeleteB() {
std::cout << "DeleteB " << std::endl;
if (fB != 0) {
std::cout << "delete fB " << std::endl;
delete fB;
fB = 0;
} else {
std::cout << "fB is already null" << std::endl;
}
}
void B::DeleteMyself() {
std::cout << "B::DeleteMyself" << std::endl;
std::cout << "this " << this << std::endl;
parent->DeleteB();
// this is printed after object is deleted
std::cout << "B::DeleteMyself after DeleteB" << std::endl;
// this has the same value
std::cout << "this " << this << std::endl;
}
的main.cpp
int main() {
// creates container A and child B
A * a = new A();
b = a->GetB();
// b will ask to its parent to be killed
b->DeleteMyself();
delete a;
}
所以我有2個問題:
- 這段代碼真的有效嗎?一旦對象被刪除,在B的函數中看起來很奇怪。
- 在GUI中實現刪除按鈕的最佳方式是什麼?
有2個解決方案,我能想到的:
重寫GUI具有用於刪除對象的單獨幀(如一個單獨的列表,獨立於幀的刪除)。但它看起來像現在一樣直觀。我有很多b,每個都有自己的刪除按鈕。
一個建議我使用一些計時器。設置一個標誌,然後調用一個函數來刪除標記爲1秒後的所有孩子。信號終止並且對象被正確刪除。我測試,似乎工作。但是這個設計看起來更像是一個詭計
我正在使用非常特定的GUI庫ROOT(http://root.cern.ch/drupal/)。 也許這個限制是由於這個框架,但我不這麼認爲。
我想清楚, 預先感謝您的建議, 邁克爾
你能解釋一下「信號/插槽機制」是什麼意思嗎? – Soren 2014-09-29 15:00:34
它是一種類似於ROOT和Qt的機制。一個按鈕發出一個咔嗒聲(信號),並且我的一個方法與它關聯(插槽)。當按鈕被刪除時,信號仍然留下,因此錯誤分段 – michael 2014-09-29 15:04:12