2016-09-27 2 views
1

GridView의 하위 클래스 (구현 here)의 데이터가 표시됩니다. 항목 추가 및 제거가 잘 작동하면 QML에 변경 사항이 통보되고 전환이 정상적으로 작동합니다.
이제 모델 내부의 Item 속성을 설정하고 QML에 응답하려고합니다. 문제는 QML 내부의 onPropertyChanged이 호출되지 않는다는 것입니다. 여기 QML이 C++ 속성 변경을 등록하지 않았습니다.

는 C++의 속성입니다 :

// item.h 
Q_PROPERTY(bool pToBeDeleted READ toBeDeleted NOTIFY toBeDeletedChanged) 

// item.cpp 
void Item::requestDelete() 
{ 
    toBeDeleted_m = true; 
    qDebug() << "emitting"; 
    emit toBeDeletedChanged(); 
} 

이것은의 GridView의 모습입니다 : gridmodel가 내 itemmodel로 설정되어

// main.qml 
GridView { 
    id: grid 

    // ... 

    model: empty 
    delegate: customComponent { 
     toBeDeleted: pToBeDeleted 
    } 
    ListModel { 
     id: empty 
    } 
} 

프로그램이 시작됩니다. 이제

// customComponentForm.ui.qml 
Item { 
    property bool toBeDeleted: false 
} 

// customComponent.qml 
CustomComponentForm { 
    onToBeDeletedChanged: { 
     console.debug("change") 
    } 
} 

이 같은 모델 내부에서 메서드를 호출 : :

this->items.at(i++)->requestDelete(); 

출력은 emitting하지만 change 보여줍니다
는 그리고이 변경 사항이 표시되지 않는 QML 유형입니다.


나는 onToBeDeletedChanged의 결과가 때로는을 를 호출 할 않았다

emit dataChanged(createIndex(i, 0), createIndex(i, 0)); 

을 포함하는 것을 시도했다, 그러나 그것은 또한 오류

DelegateModel::item: index out range 3 3 

답변

0

두 일부 불안정한 행동의 결과 여기에 문제가 발생했습니다. 첫째, 때문에

this->items.at(i++)->requestDelete(); 

dataChanged에서 ++의 잘못된 항목이 업데이트되는 결과 잘못된 인덱스를 가지고 방출한다. 모든 둘째,

emit dataChanged(createIndex(i, 0), createIndex(i, 0)); 

는 세 번째 인수 누락되었고, 또 다른 시도에서 내가 인라인 벡터의 잘못된 방향을 정의하려고했기 때문에, 나는 이것이 바로 문제 찾지 못했습니다. 여기에 전화를 걸면

QVector<int> v; 

v.append(Qt::UserRole + 7 + 1); 
// pToBeDeleted being the 7th property, always check this with 
// roleNames()[Qt::UserRole + i + 1]. It should say your property. 

emit dataChanged(createIndex(i, 0), createIndex(i, 0), v); 

내 실수.

그러나 rolename 색인은 플랫폼에 종속되어 있고 모델에서 변경된 내용이 다소 더러운 접근 방식이므로 더 나은 해결책은 (Kevin Krammer에서 제안한 것처럼) itemmodel 만 포함하도록 다시 작성하는 것입니다. 하나의 속성은 QObject 항목입니다. 그렇게하면 QML 은 변경된 항목의 속성을 알리는이됩니다.

+1

모델에 QObject 기반 항목이 있으므로 각 개체를 반환하고 개체 속성에 직접 바인딩하는 역할을 하나만 가질 수도 있습니다. 그런 다음 특정 인덱스의 객체가 변경되지 않는 한 dataChanged()를 내 보내지 않아도됩니다. 또한 하나의 고정 된 역할 만 갖고 있으므로 "roleNames with this with roleNames"와 같은 주석이 필요하지 않음을 의미합니다. –

+0

그 일은 내가하는 일보다 훨씬 좋게 들립니다. 내 모델의 변경이 어떻게 생겼는지에 대한 정보가 있습니까? –

+0

기본적으로 당신은 하나의 역할을 가지고 있고 그 역할이'data()'에 요청 될 때 그 색인에 대한 QObject 포인터를 반환합니다. 'roleNames()'가 속성 이름'object'에 매핑된다고 가정하면 QML이'someDelegateProperty : model.object.propertyOfTheObject'를 수행 할 수 있습니다 (덜 구체적인 구문을 선호한다면'model.'없이). –

관련 문제