PDA

View Full Version : type casting 5 levels down no error but not proper



sujan.dasmahapatra
24th April 2012, 13:58
I have my mainwindow which is QMainWindow the parent of all my other classes. I am type casting upwards from 5 levels down using reinterpret_cast, to access the mainwindow to display message using statusBar(), but when type casting it's not giving error but when accessing mainwindow->statusBar() it's crashing.


please check the code snippet below:



QWidget *wid = reinterpret_cast<QWidget *>(parent());
CSheet *sheet = reinterpret_cast<CSheet *>(wid->parent());
QScrollBar *scrollBar = reinterpret_cast<QScrollBar *>(sheet->parent());
CTabWidget *tabWid = reinterpret_cast<CTabWidget *>(scrollBar->parent());
CDataPage *dataPage = reinterpret_cast<CDataPage *>(tabWid->parent());
MainWindow *mainwin = reinterpret_cast<MainWindow *>(dataPage->parent());
mainwin->statusBar()->showMessage(tr("A new plot being added!!"),5000); //Here it is crashing


please help me someone whats going wrong in this. Thanks a lot for any help. Sujan

viulskiez
25th April 2012, 14:03
You are playing with the most dangerous features of C++, the pointer. I suggest you to use safer solutions.


when type casting it's not giving error
Have you check the statusBar of your mainWindow?


I have my mainwindow which is QMainWindow the parent of all my other classes
The assumption is, what you want is accessing mainWindow but the problems occurred on type casting few times. Why not creating better object relationships or singleton pattern. Or find mainWindow from QApplication::topLevelWindows by name.


I am type casting upwards from 5 levels down using reinterpret_cast, to access the mainwindow to display message using statusBar().
Do you really need to cast 5 times? That's seems odd and error prone.

ChrisW67
26th April 2012, 03:21
AARRGGHH!! Are you mad? What you have done is simply asking to fail in new and exciting ways.

A widget's parent widget is trivially obtained with QWidget::parentWidget(). You can backtrack up the hierarchy, checking for NULL as you go, and there's no need to cast anything. When you do get to the widget you want you can do a single qobject_cast<>() and check for a NULL result before continuing.

If you want the top-level window that contains this widget there's an even better way to do it: QWidget::window(). As an added bonus, this method won't break if you rearrange the widgets.

Spitfire
27th April 2012, 10:40
I agree, that's madness.

Simple solution: static method in your main window class:


static QStatusBar* status_bar = NULL;

MainWindow::MainWindow()
{
status_bar = this->statusBar();
}

void MainWindow::myStaticMethod( const QString& msg, int timeout )
{
if( status_bar )
{
status_bar->showMessage( msg, timeout );
}
}

stampede
29th April 2012, 15:04
You can always relay proper signals to some MainWindow::showStatusMessage slot. It will be a lot safer than what you are doing now.