2016-09-20 11 views
0


QQmlProperty::write(gridview, "model", QVariant::fromValue(objlist));을 호출하여 C++에서 QML GridViewmodel 속성을 설정하려고합니다. 설정하지 않고 C++에서 GridView 모델 속성 설정

gridview

모델이 표시되지 않는하지만 내가 qml: model = item(0x30617b50), Item(0x30617b90), Item(0x30617bd0), Item(0x30617c10), Item(0x30617c50), Item(0x30617cd0)
를 얻을 나는 QML에서 그들을 내가 6 개 항목으로 QList로 설정하는 경우, C++에서 속성을 수정하고 인쇄 할 수 있습니다 올바르게 설정되어 있습니다.

Qt는 설명서를

QQmlContext *ctxt = view->rootContext(); ctxt->setContextProperty("gridModel", QVariant::fromValue(objlist));

를 호출 그리고 model: gridModel와 QML의 속성을 설정하지만 그건 정말 내 요구에 맞게하지 않는 것이 좋습니다. 그것은 제대로 작동하지만, 속성이 설정되면 올바른 데이터가 표시됩니다. QML에서 변수를 인쇄 할 때 출력은
qml: model = [object Object]이므로 컨텍스트 속성을 설정하고 객체 속성을 설정하는 것과는 분명히 다른 점이 있지만이를 수정하는 방법을 모르겠습니다.

+0

'QQmlProperty :: wr을 사용하여 모델 속성을 설정하는 방법 ite' 대신'ctxt-> setContextProperty'를 사용하거나 전역 컨텍스트 변수를 사용하지 않고 GridView의 모델을 설정하는 방법을 말합니다 –

+0

C++의 모델을 _setting_하는 대신 GridView에서 빈 모델을 정의하는 옵션이 아닙니까? 및 C++에서 _update_ QAbstractItemModel 함수를 사용하여 모델? 이렇게하면 QML이 GridView를 업데이트 할 수 있도록 해당 신호가 트리거됩니다. –

+0

그게 _does_ 소리가 훨씬 더 좋아요, 특히 내 모델에서 항목을 제거하려고 할 때 문제가 생기기 때문에 더욱 그렇습니다. 그 때 정확히 어떻게 할 것입니까? 나는 C++/QML 통합에 대한 충분한 문서를 찾는 것이 매우 힘들다는 것을 알았다. –

답변

0

게시 된 답변은 게시 된 답변과 약간 다릅니다 , 나는 명확한 대답을 쓰는 것이 가장 좋을 것이라고 생각했다.

의 핵심은 QAbstractItemModel을 하위 클래스했다 (또는 더 정확하게 ..ListModel 그래서 당신은 QML ++ C의 행/열을 처리 할 필요가 없습니다).

이런 식으로 일을뿐만 아니라, 당신은 단순히 변경 모델, 예를 들면했을 경우에 반드시

QQuickItem *mainform = view->rootObject(); 
QQuickItem *grid = (QQuickItem *)mainform->findChild<QObject*>("GridView object name"); 

ItemModel itemmodel; 
itemmodel.setItems(objlist): 

QQmlProperty::write(grid, "model", QVariant::fromValue(&itemmodel)); 

또한 QML을 notifys와 속성으로 모델을 설정할 수 있습니다 항목이 삭제되었습니다.

// itemmodel.h 

#include <QAbstractListModel> 
#include <item.h> 

class ItemModel : public QAbstractListModel 
{ 
    Q_OBJECT 
public: 
    explicit ItemModel(QObject *parent = 0); 
    QHash<int, QByteArray> roleNames() const; 

public slots: 
    void setItems(QList<Item *> items); 
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; 
    int rowCount(const QModelIndex & parent = QModelIndex()) const; 
    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); 

private: 
    QList<Item *> items; 
}; 

// itemmodel.cpp 
#include "itemmodel.h" 

ItemModel::ItemModel(QObject *parent) : QAbstractListModel(parent) 
{ 

} 

// Column Names have to match all the Q_PROPERTYs defined in Item 
const char* COLUMN_NAMES[] = { 
    "property1", 
    "property2", 
    "...", 
    NULL 
}; 
QHash<int, QByteArray> makeRoleNames() 
{ 
    int idx = 0; 
    QHash<int, QByteArray> roleNames; 
    while(COLUMN_NAMES[idx]) 
     roleNames[Qt::UserRole + idx + 1] = COLUMN_NAMES[idx++]; 

    return roleNames; 
} 

QHash<int, QByteArray> ItemModel::roleNames() const 
{ 
    static const QHash<int, QByteArray> roleNames = makeRoleNames(); 
    return roleNames; 
} 

void ItemModel::setItems(QList<Item *> items) 
{ 
    this->items = items; 
} 

int ItemModel::rowCount(const QModelIndex & /* parent */) const 
{ 
    return items.count(); 
} 

bool ItemModel::removeRows(int row, int count, const QModelIndex &parent) 
{ 
    Q_UNUSED(parent); 
    beginRemoveRows(QModelIndex(), row, row + count - 1); 
    while (count--) delete items.takeAt(row); 
    // example for custom deletion: 
    //    items.takeAt(row)->removeFromRoot(); 
    endRemoveRows(); 
    return true; 
} 

QVariant ItemModel::data(const QModelIndex &index, int role) const { 
    if (!index.isValid()) 
     return QVariant(); 

    if (index.row() >= items.size() || index.row() < 0) 
     return QVariant(); 

    if (role == Qt::DisplayRole) { 
     return QVariant::fromValue(this->items.at(index.row())); 
    } 

    if (role > Qt::UserRole) 
     return this->items.at(index.row())->property(makeRoleNames()[role]); 
} 

출처 :

    다음

    내 ItemModel이다 (당신은 제대로하지만 변경 사항을 처리 할 수있는 예에 removeRows()를 볼 수 있습니다)
  • [1] Qt 설명서 페이지 QML
  • [2] QAbstractItemModel의 참조 QAbstractItemModel 서브 클래스를 생성
  • [3] QAbstractItemModel 서브 클래 싱 가이드
  • QAbstractListModel 서브 클래스
  • [5] 작업과 [4] 포럼 포스트 (거의, data() 약간 변경) QAbstractItemModel의 구현이있는 내가 데려 rolenames 함수
+0

C++에서 특정 QML 구성에 따라 C++ 코드를 사용하도록 QML 객체를 설정하지 말 것을 권장합니다. 나머지는 QML에서 사용하는 모델을 가져 오는 것과 직결되는 목록 모델 구현과 관련이있는 것으로 보이며 –

+0

질문과 직접적으로 관련이 없습니다. 처음에는 내 질문에 명시된 바와 같이 C + +에서 속성을 설정하고 싶었어요. 기존 속성을 수정하면 해결 방법이되었지만 QAbstractItemModels에 대해 자세히 조사한 후 처음에 원하는 작업을 수행 할 수 있다는 것을 알았 기 때문에 사용자의 대답이 해결 방법을 사용할 필요가 없었습니다. –

+0

귀하의 질문은 모델 속성을 설정하는 방법 이었으므로 모델 구현을 다루는 솔루션 부분이 다른 질문에 대답하고 있습니다. 누군가 다른 사람이 질문을 읽고 모델 클래스가 어떻게 연주되는지 궁금해 할 때를 대비해서 그걸 지적하고 싶었습니다. 질문의 코드와 대답의 차이점은 속성 바인딩을 통해 설정하는 대신 QObject :: setProperty를 통해보기의 모델을 설정하는 것입니다. –

0

QQmlProperty::write가 모델을 올바르게 설정한다고해서 질문이 무엇입니까?

이의 당신이 GridView 아래와 같이 있다고 가정 해 봅시다 :

GridView { 
    anchors.fill: parent 
    objectName: "grid" 
    delegate: Rectangle { 
     id: rect 
     width: 100; 
     height: 100 
     color: Qt.rgba(Math.random(),Math.random(),Math.random(),1) 
     Text { 
      anchors.centerIn: rect 
      text: modelData 
     } 
    } 
} 

objectName이 필수입니다 어쨌든 나는 또 하나 개의 솔루션을 제안한다. 그래서 C에서 접근

는 ++ 수 :

QStringList list; 
list.append("String1"); 
list.append("String2"); 
list.append("String3"); 

QQmlApplicationEngine engine; 
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 

QObject *obj = engine.rootObjects()[0]->findChild<QObject *>("grid"); 
if(obj) { 
    obj->setProperty("model",QVariant(list)); 
} 
+0

설정할 GridView 요소 당 둘 이상의 속성이 있으므로 개체 목록으로 목록이 필요합니다. 그리고 모델 속성이 올바르게 설정되어 있으면 Items 목록을 인쇄 할 때 올바른 것으로 보이는 것처럼 보이지만 아무 것도 표시되지 않습니다.GridView는 모델을 표시 할 수있는 모델을'[object object]'로 기대하지만,'item (0x30617b50), ... '으로 설정되어 있습니다. –

+0

QObject리스트를 사용하도록 예제를 다시 작성하는 것은 문제가되지 않습니다. 그리고 그것은 "항목 목록을 인쇄합니다"라는 것은 무엇을 의미합니까? 그게 뭐야? 코드를 게시 할 수 있습니까? – folibis

+0

코드를 pastebin에 넣습니다. http://pastebin.com/nPgJT5Xx –

1

대신 QML은 C에서 객체 또는 속성에 액세스하려고의 ++ 난 ++ QML 측 바인딩을 사용하여 제안 및 C에서 속성 값을 제공한다.

setContextProperty를 통해 모델 인스턴스를 표시하면 사용자의 요구 사항에 맞지 않습니다. 해당 클래스는 모델에 대한 Q_PROPERTY를 얻을 내가

  • ,

    1. 가) (setContextProperty를 통해 QObject를 파생 클래스의 인스턴스를 노출 : 모델이 QML 로딩 시간 이후 인스턴스화되면, 나는 다음과 같은 접근 방식을 제안 A는 QML에서 신호
    2. 통지를 포함하여 바인드 당신이 C++에서 모델을 만들이 있거나 모델의 새 인스턴스를 만들 필요가있을 때, 당신은 위에서 언급을 방출 신호
    3. 에 통보 할 때마다의 GridView의 모델
    4. 에 재산

    인터페이스 클래스는 다소을 만드는 경우에 C++에 당신에게 완벽하게 제어 할 수 있습니다 m_model의 변화하는 MyInterface 내부 될 수 대신 세터 물론이

    class MyInterface : public QObject 
    { 
        Q_OBJECT 
        Q_PROPERTY(MyModel* model READ model NOTIFY modelChanged) 
    
    public: 
        MyModel *model() const { return m_model; } 
    
        void setModel(MyModel *model) { 
         m_model = model; 
         emit modelChanged(); 
        } 
    
    private: 
        MyModel *m_model = 0; 
    }; 
    

    등 과 같을 것이다 모델 인스턴스, 변경시기, 삭제시기. 유형을 QAbstractItemModel * 또는 일부 일반 모델 기본 클래스로 변경하는 경우 적합하다고 판단되면 런타임 중에 모델 유형을 변경할 수도 있습니다

  • +0

    그게 나에게 유효한 접근법처럼 보입니다. 컨텍스트를 사용하여 이전 구현을 수행 했으므로 계속 진행하여 응용 프로그램을 계속 만들었지 만 이제 뷰에서 요소를 삭제할 때 문제가 발생했습니다. 그것은 보이지 않는 그것을 설정할 때 갭을 남기고 QML에서 모델의 모든 제거 메소드에 액세스하는 것처럼 보이지 않으므로 구현시 QML이 모델에서 항목을 삭제할 수 있습니까? 만약 그렇다면 어떻게 할 수 있는지 알려 줄 수 있습니까? –

    +0

    귀하의 제안과 함께 나는 [this] (http://stackoverflow.com/a/39654426/2585092) 해결책을 찾았습니다 –

    +0

    QML이 모델에서 항목을 삭제할 수 있도록 구현 했습니까? " 모델에서 항목을 삭제하는 것은 모델에 액세스하는 방법과 직교/독립적입니다. 이 모델은 행 제거에 대한 뷰를 알리기 위해 적절한 beginRemoveRows() 및 endRemoveRows() 호출을 사용하기 만하면됩니다. –