2016-07-26 6 views
0

Windows上のMy Qtクイックアプリケーションが非常に奇妙なクラッシュを経験しています。QtクイックWindowsアプリがクラッシュして、C++がベクターの要素(範囲内)にアクセスしようとしました

QObjectVectorという由来のC++クラスがあり、QML側がコンテナ内のQObjectポインタにアクセスできるようになりました。 QML側では、そのコンテナ内のオブジェクトの名前を表示するボタンがたくさんあります。マウスホイールをスクロールすると、各ボタンのcurrentItemプロパティが手動で更新されます。

奇妙、およびのみ時々、高速スクロールの予測不能数、プログラムのクラッシュ(動作を停止)した後。デバッグ後、私は、atの機能がm_data[i]になったときにクラッシュが発生することを発見しました。 iが有効な範囲[0、m_data.size()]の範囲内にあることを確認しました。したがって、これはインデックス範囲外のエラーではありません。私の推測では、どうにかして、QMLエンジンはメモリを管理しようとしているときにヒープ上のオブジェクトを削除するということです。

QObjectVector.h

#pragma once 

#include <QObject> 
#include <QVector> 

#include "Types.h" 

namespace LPP 
{ 
    class QObjectVector : public QObject 
    { 
     Q_OBJECT 

     Q_PROPERTY(Int size READ size NOTIFY sizeChanged) 

    public: 
     explicit QObjectVector(); 
     virtual ~QObjectVector(); 

     Int size(); 
     Q_INVOKABLE QObject* at(Int); 
     void push(QObject*); 
     void remove(Int); 
     void remove(QObject*); 

     QVector<QObject*> &getData(); 

     bool deleteChildrenOnDestroy; 

    private: 
     QVector<QObject*> m_data; 

    signals: 
     void sizeChanged(); 

    public slots: 
    }; 
} 

QObjectVector.cpp

... 
    QObject* QObjectVector::at(Int i) 
    { 
     qDebug() << "size: " << this->m_data.size(); 
     for (int i = 0; i < this->m_data.size(); i++){ 
      qDebug() << "i: " << i << " item: "; 
      //when I scroll rapidly, crash happens here when I trace objects in vector 
      qDebug() << this->m_data[i]; 
     } 
     qDebug() << "returning."; 
     return (i >= 0 && i < this->m_data.size()) ? this->m_data[i] : nullptr; 
    } 
.... 

ButtonContainer.qml

.... 
    //this function is called when I scroll mouse wheel. 
    //itemList contains list of Buttons 

    function refreshDisplay() { 
     var i, j = 0; 

     for (i = 0; i < itemList.length; i++){ 
      itemList[i].visible = itemList[i].enabled = false; 
     } 

     var start = Utils.clamp(Math.floor(scrollView.flickableItem.contentY/(itemHeight + itemVSpacing)), 0, currentFolder.size); 
     var end = Utils.clamp(Math.ceil((scrollView.flickableItem.contentY + scrollView.flickableItem.height)/(itemHeight + itemVSpacing)), 0, currentFolder.size); 

     var item; 

     for (i = start; i < end; i++){ 
      if (j >= itemList.length){ 
       itemList.push(tableItem_comp.createObject(tableArea)); 
      } 

      itemList[j].visible = itemList[j].enabled = true; 

      item = currentFolder.at(i); 
      itemList[j].currentItem = item; 
      j++; 
     } 
    } 
.... 

Button.qml

.... 
    property var currentItem: null; 

    anchors.left: parent.left 
    anchors.right: parent.right 

    SimpleButton { 
     id: button 
     width: 100 
     height: 50 
     text: currentItem.name; 
     onClicked: { 
      viewer.select(currentItem); 
     } 
    } 
.... 

この問題は非常に奇妙で予測不可能なことです。それを解決することは私のアプリの開発にとって非常に重要なので、どうかお願いします。

ありがとうございました!

トミー

+3

説明を削除して実際のコードを掲載してください。エラーが[MCVE]のどこにあるのか –

答えて

1

あなたが戻っているオブジェクトがQMLエンジンによって所有されているので、ゴミはいつでも収集することができるからです。

は、(それが構築されていますときなど)それはQMLに返される前に、各オブジェクトの

QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership) 

を呼び出してみてください。

は、ドキュメントのthis sectionを参照してください:データはC++からQMLに転送されると

、データの所有権は常に、C++でのまま。このルールの例外は、明示的なC++メソッド呼び出しからQObjectが返された場合です。この場合、QMLエンジンはオブジェクトの所有権を明示的に設定していないかぎり、QQmlEngine :: QQmlEngine :: CppOwnershipが指定されたsetObjectOwnership()。

さらに、QMLエンジンはQt C++オブジェクトの通常のQObject親所有権セマンティクスを尊重し、すでに親を持つQObjectインスタンスの所有権を取得することはありません。

+1

また、オブジェクトは親を使って構築することもできます – wasthishelpful

+0

うわあ、ありがとう!ところで、私が直面していた問題は、私のC++オブジェクトがガベージコレクションされたためですか?編集:ちょうどあなたの編集を見た。 – TommyX

+1

Yep;それを含む答えを更新しました。 – Mitch

関連する問題