自定义QDialog导致exec()上的段错误

时间:2013-09-13 14:17:07

标签: c++ qt segmentation-fault qdialog custom-widgets

我有一个程序,它基本上由一个中心QMainWindow和一个成员QToolbar指针组成。

此工具栏上的一个操作将triggered信号连接到ShowNodeEditBox()插槽,该插槽实例化并尝试执行自定义的QDialog派生小部件:

 void
 Toolbar::ShowNodeEditBox(){
   ...
   //Side note: The custom box stores a pointer to a custom QGLWidget on the main window
   NodeEditBox nodeEdit(this, m_mainWindow->GetGLScene());
   nodeEdit.exec(); 
 }

出于某种原因,调用exec会导致段错误,即使只是在没有它的情况下构建窗口也可以正常工作。堆栈跟踪如下:

#0  0x0000000000000000 in ?? ()
#1  0x00000030922e64ff in ?? () from /usr/lib64/libQtGui.so.4
#2  0x00000030922e795a in QPainter::QPainter(QPaintDevice*) () from /usr/lib64/libQtGui.so.4
#3  0x00000030921fd7af in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib64/libQtGui.so.4
#4  0x00000030923a0675 in ?? () from /usr/lib64/libQtGui.so.4
#5  0x00000030923a09c9 in ?? () from /usr/lib64/libQtGui.so.4
#6  0x00000030922162da in ?? () from /usr/lib64/libQtGui.so.4
#7  0x00000030922213e7 in QApplication::x11ProcessEvent(_XEvent*) () from /usr/lib64/libQtGui.so.4
#8  0x0000003092249da2 in ?? () from /usr/lib64/libQtGui.so.4
#9  0x00007ffff7410f0e in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#10 0x00007ffff7414938 in ?? () from /lib64/libglib-2.0.so.0
#11 0x00007ffff7414a3a in g_main_context_iteration () from /lib64/libglib-2.0.so.0
#12 0x0000003091b7d5f3 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#13 0x0000003092249a6e in ?? () from /usr/lib64/libQtGui.so.4
#14 0x0000003091b56722 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#15 0x0000003091b569ec in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQtCore.so.4
#16 0x000000309262aaae in QDialog::exec() () from /usr/lib64/libQtGui.so.4
#17 0x000000000045d9e8 in RoadmapOptions::ShowNodeEditBox (this=0xce5da0) at GUI/RoadmapOptions.cpp:562
#18 0x0000000000486f32 in RoadmapOptions::qt_metacall (this=0xce5da0, _c=QMetaObject::InvokeMetaMethod, _id=12, _a=0x7fffffffc740)
    at GUI/MOC/moc_RoadmapOptions.cpp:114

肯定会有一些东西在这里,因为我看到了0x0,但我无法弄明白。 NodeEditBox本身的构造非常复杂(遍布各处的滑块,标签等),所以我尝试将其全部清除,只需在一个空的自定义框上调用exec,构造如下: / p>

NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene){ /* nothing! */ }

瞧瞧(也许谢天谢地,因为它是一个非常复杂的小部件),这会导致完全相同的段错误!我还尝试使用NodeEditBox创建指向new的指针,而不仅仅是实例化它,以及使NodeEditBox成为工具栏类的指针成员并更早地构造它(因此,仅在exec中进行ShowNodeEditBox()。据我所知,父和GLWidget场景指针已经创建,计算和强大。但我每次都会遇到同样的问题。

我在这里缺少什么?

**其他信息/编辑:使用常规的空QDialog并弹出它而不是自定义版本可以正常工作。所以也许这是与父母有关的事情。

更有趣的是,从NodeEditBox而不是QWidget派生QDialog的工作正常并且不会崩溃!我想使用QDialog,所以我可以调用exec. show似乎不起作用,除非NodeEditBox是工具栏类的成员,我不想要因为我需要多个“一次性”节点编辑框在不同的时间弹出...

2 个答案:

答案 0 :(得分:1)

应该是

NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene)
: QDialog(parent)
{ /* nothing! */ }

而不是

NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene){ /* nothing! */ }
  • 你需要传递输入参数,otehrwise默认ctor被调用unbderlying widget,0父。不是100%确定这是否会导致段错误,但肯定容易出错。

答案 1 :(得分:0)

我认为这里没有足够的信息来解决这个问题,所以我会采取以下措施来缩小范围:

  1. 确保您可以通过一个干净的干净构建(即make clean等)重现此崩溃。有时“不太神秘”的崩溃可能是由不洁的构建(过时的对象/ moc文件等)引起的。

  2. 从一个简单版本的NodeEditBox开始,然后解决崩溃问题。您已经删除了构造函数 - 对所有其他方法和成员执行相同操作。将它们全部注释掉,然后将它们一块一块地放回去,找到使其崩溃的最小版本。也许发布那个最小版本,如果它对你来说仍然没有意义。

  3. 不要使用替代实现进行侧向跟踪 - 您提供的代码看起来没问题 - 您应该能够使其工作。崩溃的原因必须在您未在此处显示的代码中。