[英]Calling width(), height(), size() or rect() inside subclass of QWidget ends with segfault
我對QWidget
的width()
, height()
, size()
或rect()
函數有問題; 調用它時會出現段錯誤。 這是Qt 4.7。
這是有問題的類的標題:
class PlotCanvas : public QWidget
{
void paintEvent(QPaintEvent * e);
uint64_t smallestDiv();
uint64_t longestLength();
void drawGrid(QPainter * painter);
QVector<Plot*> plots;
int calculateHeight() const;
int calculateWidth() const;
uint32_t cursorPosition;
public:
PlotCanvas(QWidget * parent = 0) : QWidget(parent)
{
setStyleSheet("background-color: black");
setAutoFillBackground(true);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setFocusPolicy(Qt::StrongFocus);
update();
}
void addPlot(Plot * plot);
int getDivCount();
};
和實際的段錯誤代碼:
int PlotCanvas::getDivCount()
{
QRect bounds = rect(); //segfaults
qDebug() << bounds.size().width();
qDebug() << bounds.size().height();
return 10;
}
追溯到Qt的qrect.h
:
inline int QRect::width() const
{ return x2 - x1 + 1; } //this line finally kills it
看起來QWidget
內部似乎沒有正確初始化一些東西,但是我不知道是什么,因為如您所見,我並沒有真正改變QWidget
初始化。
PlotCanvas
小部件位於QAbstractScrollArea
子類中(尚未實現,因此只是普通的QAbstractScrollArea
:
class PlotCanvasScrollArea : public QAbstractScrollArea
{
public:
PlotCanvasScrollArea(QWidget * parent = 0) : QAbstractScrollArea(parent)
{
}
};
我只需要確定QWidget
繪畫區域的大小,因為我正在繪制過渡圖,並且我需要知道多少時分適合當前的窗口小部件大小,因為顯然應用程序窗口是可調整大小的。
編輯:
構建PlotCanvas
代碼:
Board(QString & name) : name(name)
{
hbox = new QHBoxLayout();
commonKnobGroup = new QGroupBox("Common settings:");
commonKnobGroup->setMinimumWidth(190);
commonKnobGroup->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
commonKnobs = new CommonKnobs(commonKnobGroup);
hsplitter = new QSplitter();
plotGroupBox = new QGroupBox("Measurement plots:", hsplitter);
settingsGroupBox = new QGroupBox("Plot settings:", hsplitter);
plotSplitter = new QSplitter();
plotHbox = new QHBoxLayout();
plotHbox->addWidget(plotSplitter);
plotGroupBox->setLayout(plotHbox);
settingsVLayout = new QVBoxLayout();
plotNamesColumn = new QListWidget(plotSplitter);
scrollArea = new PlotCanvasScrollArea(plotSplitter);
//scrollArea->setWidgetResizable(true);
plotsCanvas = new PlotCanvas();
scrollArea->setViewport(plotsCanvas);
scrollArea->setBackgroundRole(QPalette::Dark);
specializedKnobGroup = new QGroupBox("Probe settings:");
plotSettings = new QStackedWidget(specializedKnobGroup);
settingsVLayout->addWidget(commonKnobGroup);
settingsVLayout->addWidget(specializedKnobGroup);
settingsGroupBox->setLayout(settingsVLayout);
hbox->addWidget(hsplitter);
setLayout(hbox);
connect(plotNamesColumn, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this,
SLOT(changePageNames(QListWidgetItem*, QListWidgetItem*)));
connect(commonKnobs, SIGNAL(scaleUpdated()), plotsCanvas, SLOT(update()));
};
編輯2:
完整的堆棧跟蹤:
#0 0x000000010000b9ac in QWidget::rect() const at /Volumes/Data/shinji/QtSDK/Desktop/Qt/474/gcc/include/QtGui/qwidget.h:1007
#1 0x000000010000b454 in PlotCanvas::getDivCount() ()
#2 0x000000010000ab39 in Board::getDivCount() ()
#3 0x0000000100009fbc in CommonKnobs::updateScaleByBeginEnd() ()
#4 0x00000001000015b4 in CommonKnobs::qt_metacall(QMetaObject::Call, int, void**) ()
#5 0x0000000100d09b66 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
#6 0x000000010070df9d in QSpinBox::valueChanged(int) ()
#7 0x00000001004d9684 in QSpinBoxPrivate::emitSignals(EmitPolicy, QVariant const&) ()
#8 0x000000010043b321 in QAbstractSpinBoxPrivate::setValue(QVariant const&, EmitPolicy, bool) ()
#9 0x000000010043c11a in QAbstractSpinBoxPrivate::_q_editorTextChanged(QString const&) ()
#10 0x000000010043cca7 in QAbstractSpinBox::qt_metacall(QMetaObject::Call, int, void**) ()
#11 0x000000010070e435 in QSpinBox::qt_metacall(QMetaObject::Call, int, void**) ()
#12 0x0000000100d09b66 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
#13 0x000000010048a1e6 in QLineEdit::textChanged(QString const&) ()
#14 0x000000010048d23a in QLineEdit::qt_metacall(QMetaObject::Call, int, void**) ()
#15 0x0000000100d09b66 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) ()
#16 0x000000010070c9f9 in QLineControl::textChanged(QString const&) ()
#17 0x0000000100494337 in QLineControl::finishChange(int, bool, bool) ()
#18 0x0000000100496664 in QLineControl::processKeyEvent(QKeyEvent*) ()
#19 0x000000010048b8eb in QLineEdit::keyPressEvent(QKeyEvent*) ()
#20 0x00000001001056bd in QWidget::event(QEvent*) ()
#21 0x000000010048c18b in QLineEdit::event(QEvent*) ()
#22 0x000000010043d9f0 in QAbstractSpinBox::keyPressEvent(QKeyEvent*) ()
#23 0x00000001001056bd in QWidget::event(QEvent*) ()
#24 0x000000010043bb1b in QAbstractSpinBox::event(QEvent*) ()
#25 0x00000001004d7be5 in QSpinBox::event(QEvent*) ()
#26 0x00000001000a9e8d in QApplicationPrivate::notify_helper(QObject*, QEvent*) ()
#27 0x00000001000b198b in QApplication::notify(QObject*, QEvent*) ()
#28 0x0000000100d0321c in QCoreApplication::notifyInternal(QObject*, QEvent*) ()
#29 0x00000001000a9f2c in qt_sendSpontaneousEvent(QObject*, QEvent*) ()
#30 0x0000000100125cc1 in QKeyMapper::sendKeyEvent(QWidget*, bool, QEvent::Type, int, QFlags<Qt::KeyboardModifier>, QString const&, bool, int, unsigned int, unsigned int, unsigned int, bool*) ()
#31 0x0000000100126b43 in QKeyMapperPrivate::translateKeyEvent(QWidget*, OpaqueEventHandlerCallRef*, OpaqueEventRef*, void*, bool) ()
#32 0x000000010006072e in qt_dispatchKeyEvent(void*, QWidget*) ()
#33 0x000000010005478b in -[QCocoaView keyDown:] ()
#34 0x00007fff815a90c7 in -[NSWindow sendEvent:] ()
#35 0x0000000100059891 in -[QCocoaWindow sendEvent:] ()
#36 0x00007fff814ddafa in -[NSApplication sendEvent:] ()
#37 0x000000010005cf0a in -[QNSApplication sendEvent:] ()
#38 0x00007fff814746de in -[NSApplication run] ()
#39 0x0000000100066c04 in QEventDispatcherMac::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
#40 0x0000000100def774 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
#41 0x0000000100defa94 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) ()
#42 0x0000000100df10bc in QCoreApplication::exec() ()
#43 0x0000000100001cf6 in main ()
看一下崩潰堆棧跟蹤-它是否在某個地方通向構造函數? 我的第一個想法是,我不確定您是否應該在構造函數中調用update-我可能不在基礎上,但這對我來說似乎是錯誤的。 如果update應該在QWidget構造函數中調用,則基本構造函數將調用它(使您的調用成為多余的),否則,我根本不知道會發生什么。
您的scrollArea是作為plotSplitter的子級創建的,但永遠不會使用addWidget()添加到拆分器中,此外plotSplitter沒有父級,這意味着它將是自己的窗口。 我可以想象問題可能出在將scrollArea的視口設置為plotsCanvas時,而后者是另一個沒有父級的QWidget,因此也沒有它自己的窗口。
嘗試這樣的事情,然后從那里開始工作:
Board(QString & name) : name(name)
{
hbox = new QHBoxLayout();
commonKnobGroup = new QGroupBox("Common settings:");
commonKnobGroup->setMinimumWidth(190);
commonKnobGroup->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
commonKnobs = new CommonKnobs(commonKnobGroup);
hsplitter = new QSplitter();
plotGroupBox = new QGroupBox("Measurement plots:", hsplitter);
settingsGroupBox = new QGroupBox("Plot settings:", hsplitter);
plotSplitter = new QSplitter(this);
plotHbox = new QHBoxLayout();
plotHbox->addWidget(plotSplitter);
plotGroupBox->setLayout(plotHbox);
settingsVLayout = new QVBoxLayout();
plotNamesColumn = new QListWidget(plotSplitter);
scrollArea = new PlotCanvasScrollArea(plotSplitter);
plotSplitter->addWidget(plotNamesColumn);
plotSplitter->addWidget(scrollArea);
//scrollArea->setWidgetResizable(true);
plotsCanvas = new PlotCanvas(this);
scrollArea->setViewport(plotsCanvas);
scrollArea->setBackgroundRole(QPalette::Dark);
specializedKnobGroup = new QGroupBox("Probe settings:");
plotSettings = new QStackedWidget(specializedKnobGroup);
settingsVLayout->addWidget(commonKnobGroup);
settingsVLayout->addWidget(specializedKnobGroup);
settingsGroupBox->setLayout(settingsVLayout);
hbox->addWidget(hsplitter);
setLayout(hbox);
connect(plotNamesColumn, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this,
SLOT(changePageNames(QListWidgetItem*, QListWidgetItem*)));
connect(commonKnobs, SIGNAL(scaleUpdated()), plotsCanvas, SLOT(update()));
};
嘗試使用小部件geometry
而不是rect
。 另外,請注意復制構造函數。 如果使用成員變量,則需要使用setGeometry或setRect代替副本構造函數。
請參閱Qt Window Geometry文檔。
我已經解決了它,它使用了parent()作為指向Board的指針(使用scatic_cast進行了廣播,我認為使用static_cast轉換為錯誤的對象會殺死它,但不會)從PlotCanvas和我正在使用的另一個類中實際上,如果是PlotCanvas,則將parent()引用到PlotCanvasScrollArea;如果是其他類,則將其引用到QGroupBox。
調試器顯示出我實際上跳入了Board的代碼,甚至認為被調用對象的地址是完全錯誤的,這很奇怪,而更奇怪的是,它崩潰了而不是起源於PlotCanvas代碼(Board的代碼)。
但是現在可以了。 感謝大伙們 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.