Problem with QTabWidget::addTab() ?
-
wrote on 27 Apr 2014, 18:23 last edited by
Hi, I'm trying to add a tab inside a QTabWidget using the code below:
@
void test_addtab(QTabWidget parent, QString tabname){
QWidget newtab = new QWidget(parent);
parent->addTab(newtab, tabname);
}@but this code was causing a program crash, so how to solve the problem? thanks.
-
wrote on 27 Apr 2014, 18:49 last edited by
Is parent eventually 0?
-
wrote on 27 Apr 2014, 18:52 last edited by
no, the parent is a QTabWidget that is valid(I tested that by myself through outputting its objectName() into a QMessageBox()).
-
Hi,
What does a run using the debugger tells you about the crash ?
-
wrote on 27 Apr 2014, 20:23 last edited by
I got exception at 0x67b05545, code: 0xc0000005: read access violation at: 0x0, flags=0x0:
QtGui4!ZN14QStackedWidget12insertWidgetEiP7QWidget:
0x67b0553c <+0x0000> push ebp
0x67b0553d <+0x0001> mov ebp,esp
0x67b0553f <+0x0003> sub esp,8
0x67b05542 <+0x0006> mov eax,dword ptr [ebp+8]
here: 0x67b05545 <+0x0009> mov eax,dword ptr [eax+4] -
So you are indeed accessing something that's not pointing to the right place.
Where do you check that parent is valid ?
-
wrote on 27 Apr 2014, 20:54 last edited by
I'm sure that the parent is valid, I've just tested now this code:
@QMessageBox::information(0,0,tabrecapTab->objectName());
test_addtab(tabrecapTab, "test");@
when this code was executed: a messagebox containing the parent objectName was shown, but just after that the program crashs, but when removing the line of @test_addtab(tabrecapTab, "test");@ there is no crash. -
wrote on 27 Apr 2014, 20:56 last edited by
How where and how is tabrecapTab created? Any chance it is dangling?
Anyway, just to be sure, edit your code like this:
@void test_addtab(QTabWidget parent, QString tabname)
{
if(parent)
{
QWidget newtab = new QWidget(parent);
parent->addTab(newtab, tabname);
}
else
{
qWarning("Parent is NULL !!!");
}
}@ -
wrote on 27 Apr 2014, 20:59 last edited by
[quote author="MuldeR" date="1398632164"]How where and how is tabrecapTab created? Any chance it is dangling?
Anyway, just to be sure, edit your code like this:
@void test_addtab(QTabWidget parent, QString tabname)
{
if(parent)
{
QWidget newtab = new QWidget(parent);
parent->addTab(newtab, tabname);
}
else
{
qWarning("Parent is NULL !!!");
}
}@[/quote]
it's created using the ui designer, not programmatically.
I tested if the parent is null, and I'm sure that isn't. -
wrote on 27 Apr 2014, 21:15 last edited by
[quote author="SGaist" date="1398631643"]So you are indeed accessing something that's not pointing to the right place.
Where do you check that parent is valid ?[/quote]
I"ve tested if the parent was really null using the code below:
@ if (!tabrecapTab) QMessageBox::information(0,0,"invalid parent");
test_addtab(tabrecapTab, "test");@
but when the program runs: no "invalid parent" message was shown.
so I'm sure that the parent is not null. -
wrote on 27 Apr 2014, 21:17 last edited by
[quote author="kaisbs" date="1398632357"]
I tested if the parent is null, and I'm sure that isn't.[/quote]It still doesn't hurt to make your function safe for NULL pointers.
Anyway, even a non-NULL pointer is not guaranteed to (still) be valid:
http://en.wikipedia.org/wiki/Dangling_pointer
__
Also you should make a Debug build. When it crashes, find out where exactly in the code it crashes and why. Otherwise everything is speculation.
-
wrote on 27 Apr 2014, 22:01 last edited by
I understand now the cause of this crash: because the parent is QWidget that doesn't have the addTab method, and that I've used as @QTabWidget*@ by getting it via @getChild@ then casting it to @QTabWidget*@,
that was completely wrong, so my advice is : "never get widgets using getChild, instead use ui->widget".
I still have to tell you now: thank you so much for your appreciated help! -
wrote on 27 Apr 2014, 22:58 last edited by
Glad you fixed the problem.
Side note: If you ever have to cast a pointer from a base class to a derived class, like from QWidget to QTabWidget, it is inherently unsafe! If you have to do that, then, most of the time, you probably need to rethink the design of your code. But if you really cannot get around this, use dynamic_cast at least. And don't forget to check the result of the dynamic cast for NULL ;-)
-
For QObjects derived classes, you should use qobject_cast, if it fails for another reason than wrong "class name" then it will indicate that you are doing something funky somewhere.
1/14