У меня есть программа, которая по сути состоит из центрального 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 вызывает ошибку segfault, хотя просто создание окна без него работает просто отлично. Трассировка стека выглядит следующим образом:
#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 для пустого пользовательского окна, сконструированного так:
NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene){ /* nothing! */ }
О чудо (и, возможно, к счастью, поскольку это действительно сложный виджет), это вызывает точно такой же segfault! Я также попытался сделать указатель на NodeEditBox
с new
вместо того, чтобы просто создавать его, а также делать NodeEditBox
член-указатель класса панели инструментов и создание его ранее (таким образом, только делая exec
в ShowNodeEditBox()
, И родительские и GLWidget сценарные указатели уже созданы, учтены и надежны, насколько я знаю. Но я все равно получаю одну и ту же проблему каждый раз.
Что мне здесь не хватает?
** Другая информация / редактировать: используя обычный, пустой QDialog
и вытащить его вместо пользовательской версии работает просто отлично. Так что, возможно, это связано с родителями.
Еще интереснее, выводя NodeEditBox
от QWidget
вместо QDialog
работает просто отлично и не вылетает! Я хотел использовать QDialog
Впрочем, чтобы я мог позвонить exec.
show
кажется, не работает, если NodeEditBox
является членом класса панели инструментов, который мне не нужен, потому что мне нужно, чтобы несколько «одноразовых» окон редактирования появлялись в разное время …
Должно быть
NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene)
: QDialog(parent)
{ /* nothing! */ }
вместо
NodeEditBox::NodeEditBox(QWidget* _parent, GLWidget* _scene){ /* nothing! */ }
Я не думаю, что здесь достаточно информации, чтобы решить эту проблему, поэтому вот что я хотел бы сделать, чтобы сузить ее:
Убедитесь, что вы можете воспроизвести этот сбой из скрипучей чистой сборки (т.е. make clean
, так далее). Иногда «таинственные» сбои могут быть вызваны нечистой сборкой (устаревшие объекты / файлы moc и т. Д.).
Начните с тривиальной версии NodeEditBox и работайте в направлении сбоя. Вы уже заглушили конструктор — сделайте то же самое со всеми другими методами и членами. Закомментируйте их все, а затем сложите их по частям, чтобы найти минимальную версию, которая приводит к сбою. Может быть, опубликовать эту минимальную версию, если она все еще не имеет смысла для вас.
Не отвлекайтесь на альтернативные реализации — код, который вы представили, выглядит нормально — вы должны быть в состоянии заставить его работать. Причина сбоя должна быть в коде, который вы здесь не указали.