2013-08-24 101 views
1

我遇到了一些直接脫離Qt幫助的QRubberBand代碼崩潰。崩潰發生在setGeometry呼叫。 QRubberBand實例已經創建,因爲我能夠使用qDebug訪問幾何,所以我很困惑。QRubberBand:崩潰與BAD ACCESS錯誤

此背景情況:該代碼是在一個自定義的Widget這是這樣創建的:

ImageLabel2* image = new ImageLabel2(this); 
    image->setPixmap(pix); 
    setCentralWidget(image); 

我所知道的情況仍然存在,因爲註釋掉setGeometry呼籲避免崩潰,調試語句繼續被輸出。

我在做什麼明顯錯誤?

調試輸出:

mousePress QPoint(294343)
該程序已意外結束。


從崩潰日誌:

異常類型:EXC_BAD_ACCESS(SIGSEGV)異常代碼: 0x000000000000000d,0x0000000000000000


代碼:

void ImageLabel2::mousePressEvent(QMouseEvent *event) 
{ 
    qDebug() << "mousePress" << event->pos(); 

    origin = event->pos(); 

    if (!rubberBand){ 
     rubberBand = new QRubberBand(QRubberBand::Rectangle, this); 
    } 
    qDebug() << rubberBand->geometry(); 
    rubberBand->setGeometry(QRect(origin, QSize())); // CRASH 
    rubberBand->show(); 
} 

回答

2

UPD:根據新信息,問題是初始化。

通過具有檢查

if (!rubberBand){ 
    rubberBand = // initialize it 
} 

您預計rubberBand指針是最初等於零(NULL),你檢查它。但是,除非你初始化了這個指針,否則它將不等於0,也不等於某個正確的地址。像任何其他未初始化的變量一樣,它將包含垃圾,即當時在內存中碰巧存在的一些隨機值。使用這樣的指針將保證崩潰。

所以,對未初始化的變量說不!如果你想讓它初始爲NULL,使其爲 NULL。

因此,在自定義窗口小部件的構造函數初始化它像

ImageLabel2::ImageLabel2() : rubberBand(NULL) { 
    // your constructor code 
} 

ImageLabel2::ImageLabel2() { 
    rubberBand = NULL; 
    // your constructor code 
} 

(沒有區別)。如果您願意,也可以寫0而不是NULL,但NULL更常見。

之後,不應該需要修改mousePressEvent方法。


老答案(錯誤):

從文檔QSize default constructor

QSIZE :: QSIZE()

構造一個大小與一個無效的寬度和高度 (即,isValid()返回false)。

所以,你創建一個無效 QSize並將其傳遞給QRect。之後的崩潰可能是QRect或QRubberBand的代碼中的某種錯誤,或者是種類未定義的行爲。如果你想要0的大小0,那麼你應該使用QSize(0,0),我想。這樣的尺寸將是有效

布爾QSIZE ::的isValid()const的

返回true如果二者的寬度和高度是等於或大於0;否則返回false。

+0

謝謝 - 我已經檢查了與使用'QRubberBand :: setGeometry(INT的x,INT Y,INT寬度,INT高度)試圖'同樣的崩潰。我已經縮小到條件化的'if(!rubberBand)'永遠不會進入,所以對象永遠不會被創建。奇。 –

+0

然後檢查'rubberBand'字段是否在構造函數中初始化爲NULL。否則,這個指針可能包含*垃圾*因此在不等於0時不正確。 – NIA

+0

該代碼來自Qt幫助; 'rubberBand'在我的自定義Widget頭文件中聲明,但直到第一個mouseDown事件(延遲加載)才被初始化,所以條件應該會觸發但不會。如果我在我的類構造函數中顯式初始化'rubberBand',那麼它就像預期的那樣工作。 –

0

您錯誤可能來自您傳遞QSize()作爲參數的事實。

如文檔狀態,QSIZE的默認構造創建無效對象