Ich erhalte eine Segmentierungsverletzung in meinem zweiten Aufruf an QGraphicsScene :: addItem().QT 5.6: Segmentierungsverletzung im zweiten Aufruf von QGraphicsScene :: addItem()
Der folgende Code funktioniert das erste Mal, aber nach dem Beenden/Neuladen von QDialog, QApplication, etc. (aufgerufen in einer DLL), Fehler Code konsequent bei der zweiten Verwendung mit dem gleichen Bild!?!
Ich frage mich, ob die Destruktoren sauber beendet wurden, oder ob ich QApplication möglicherweise neu initialisieren muss.
Vorschläge, bitte? Hier ist mein Code in Frage ...
PBITMAPINFOHEADER pDIBInfoHeader = (PBITMAPINFOHEADER)m_pImage;
QGraphicsScene *pgs = new QGraphicsScene();
pgs->setSceneRect(0.0, 0.0, 70.0, 80.0);
QSize qs(70, 80);
int width = pDIBInfoHeader->biWidth;
int height = pDIBInfoHeader->biHeight;
uchar *pBits = (uchar *)m_pImage + sizeof(BITMAPINFOHEADER);
QImage *pqi = new QImage((uchar *)pBits, width, height, QImage::Format_Grayscale8);
QImage qiFlip = pqi->mirrored(false, true); //flip image vertically
delete pqi;
QPixmap *ppm = new QPixmap;
if (!ppm->convertFromImage(qiFlip.scaled(qs, Qt::KeepAspectRatio), Qt::NoFormatConversion))
cdbg << "ppm->convertFromImage false" << endl;
// DOES QGRAPHICSPIXMAPITEM TAKE OWNERSHIP OF QPIXMAP?
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(*ppm, 0);
delete ppm;
pgs->addItem(item); // <<< SIGSEGV
ui->grXray->setScene(pgs);
Hinweise: Pgs ist das einzige Element in der Szene. Die Szene ist nicht aktiv.
Ich habe QT mit Debug-Optionen für Windows MSVC 2015 neu aufgebaut und kann viele Details sehen, aber die Feinheiten von C++ - Vorlagen, QVariant und QMetaType entgehen mir. Wo soll ich nach Korruption suchen?
Hier ist Call-Stack von SIGSEGV:
QMetaType::construct(void * where, const void * copy) Line 2153 C++
`anonymous namespace'::customConstruct(QVariant::Private * d, const void * copy) Line 1020 C++
QVariant::QVariant(const QVariant & p) Line 1372 C++
QGraphicsItem::itemChange(QGraphicsItem::GraphicsI temChange change, const QVariant & value) Line 7447 C++
QGraphicsScene::addItem(QGraphicsItem * item) Line 2496 C++
QT Code-Schnipsel:
inline void *QMetaType::construct(void *where, const void *copy) const
{
if (Q_UNLIKELY(isExtended(ConstructEx)))
return constructExtended(where, copy);
return m_constructor(where, copy); //<<<<<<<<
}
QVariant::QVariant(const QVariant &p)
: d(p.d)
{
if (d.is_shared) {
d.data.shared->ref.ref();
} else if (p.d.type > Char) {
handlerManager[d.type]->construct(&d, p.constData()); //<<<<<<
d.is_null = p.d.is_null;
}
}
void QGraphicsScene::addItem(QGraphicsItem *item)
...
// Notify the item that its scene is changing, and allow the item to
// react.
const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
QVariant::fromValue<QGraphicsScene *>(this))); // <<<<<<<<<
Müssen Sie Ihr QApplication-Objekt wirklich zerstören und neu erstellen? Die meisten Qt-Programme behalten ein einzelnes QApplication-Objekt für die Dauer des Prozesses bei (z. B. als ein Stapelobjekt nahe dem Anfang von main() oder Ähnlichem deklariert); Ich vermute, dass das Zerstören und Wiederherstellen des QApplication-Objekts etwas ist, das die Qt-Entwickler nicht erwartet haben, so dass dort ein Fehler liegen kann, den sie nicht kennen. –
Hmm, unser Anwendungsframework löscht QApplication bei Beendigung. Ich habe versucht, dieses Löschen zu überspringen, und habe SIGSEGV immer noch tief in QCoreApplication :: postEvent(); – Lee