2回目のQGraphicsScene :: addItem()呼び出しでセグメント化違反が発生し続けます。QT 5.6:QGraphicsScene :: addItem()の2回目の呼び出しでセグメンテーション違反が発生しました
次のコードは初めて動作しますが、(DLLで呼び出された)QDialog、QApplicationなどを終了/再読み込みした後、同じ画像で2回目の使用でコードが一貫して失敗します。
デストラクタが正常終了したかどうか、あるいはQApplicationを別の方法で再初期化する必要があるかもしれません。
提案してください。ここで問題になっている私のコード...
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);
注意事項は以下のとおりです。PGSは、シーン内の唯一の項目です。シーンはアクティブではありません。
Windows MSVC 2015のデバッグオプションを使用してQTを再構築しましたが、詳細はよくわかりますが、C++テンプレート、QVariant、QMetaTypeの複雑さが私を逃しています。どこで腐敗を探すべきですか?
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コードスニペット:
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))); // <<<<<<<<<
本当にQApplicationオブジェクトを破棄して再作成する必要がありますか?ほとんどのQtプログラムは、プロセスの持続時間中に単一のQApplicationオブジェクトを保持します(例えば、スタックオブジェクトとしてmain()の最上部近くに宣言されているなど)。私は、QApplicationオブジェクトを破棄して再作成することは、Qt開発者が予期していなかったものだと考えています。だから、気づいていないバグがあるかもしれません。 –
弊社のアプリケーションフレームワークは、終了時にQApplicationを削除します。私はその削除をスキップしようとしましたが、QCoreApplication :: postEvent()ではまだSIGSEGVが深いです。 – Lee