2

QAbstractItemModelアタッチされた派生クラスがありQTreeViewます。

モデルは 2 つの最上位行を実装し、そのうちの 1 つには 3 つのサブ行があります。最初の 2 つのサブ行のみが表示されます。「ダミー」の最上位行を 1 つ追加すると、すべてが表示されます。

以前は、自分とどのインデックスを使用qDebug()して何回QTreeView呼び出したかを出力していました (場合のみが出力されます)。実際には、サブ行に対して 3 回ではなく 2 回呼び出されていることがわかります。model::data()Qt::DisplayRole

もちろん、最初の疑惑は mymodel::rowCount()が正しくなく、QTreeViewサブ行が 2 つしかないと「思わせる」ことです。だからここにqDebug()プリントがあります:

rowCount returning 3 for parent 0xbc6f70
…….
Qt::DisplayRole for row 0 ,column 0 pointer 0xbc6fc0 parent= 0xbc6f70
Qt::DisplayRole for row 1 ,column 0 pointer 0xbc7068 parent= 0xbc6f70

ここで、0xbc6f70 は次のとおりです。

  • parent.internalPointer()model::rowCount(const QModelIndex &parent)
  • index.parent().internalPointer()model::data(const QModelIndex &index, int role)

では、なぜmodel::data()行 0 と行 1 に対して呼び出されているのに、行 2 に対して呼び出されていないのにmodel::rowCount()、インデックスに対して 3 が返されたのinternalPointer() 0xbc6f70ですか?

コードは次のとおりです。

int Model_Tree::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid())
{
    // This is 1st level
    qDebug() << "rowCount returning m_RowCount" << m_RowCount << "for !parent.isValid()" << parent.internalPointer() << "row" << parent.row() << "column" << parent.column();
    return m_RowCount;
}

int column = parent.column();
if(0 != column)
{
    qDebug() << "rowCount returning 0 for parent 0 != column (" << column << ")";
    return 0; // only item at 0th column can have children
}

const TreeItem* pTreeItem = (const TreeItem*)parent.internalPointer();
if (0 == pTreeItem)
{
    qDebug() << "rowCount returning 0 for parent 0==pTreeItem" << pTreeItem;
    return 0;
}

qDebug() << "rowCount returning " << pTreeItem->m_Children.size() << "for parent " << pTreeItem << "type:" << pTreeItem->m_type;
return pTreeItem->m_Children.size();
}

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

switch (role)
{
case Qt::TextAlignmentRole:
    return Qt::AlignTop;
case Qt::DisplayRole:
    void* p = index.internalPointer();
    int column = index.column();
    int row = index.row();
    qDebug() << "Qt::DisplayRole for row " << row << ",column " << column << "pointer" << p << "parent=" << index.parent().internalPointer();
// .... the rest of Model_Tree::data implementation
}

ここに qDebug() の出力があります。

rowCount returning  3 for parent  **0x122ee138** type: 0
....
Qt::DisplayRole for row  0 ,column  0 pointer 0x122ee168 parent= **0x122ee138**
Qt::DisplayRole for row  1 ,column  0 pointer 0x122ee198 parent= **0x122ee138** 

0x122ee138 - これは、3 つの子を含む親ノードの「internalPointer」値です。

index() と parent() の実装は次のとおりです。

QModelIndex Model_Tree::index(int row, int column, const QModelIndex &parent) const
{
    void* p = 0;

    if (!parent.isValid())
    {
        // This is 1st level
        // we use our whole record

        if (row < m_RowCount)
        {
            const TreeItem& treeItem = *(m_pRootItem->m_Children.at(row));
            const LogRecord* pRecord = treeItem.m_pRecord;
            const LogRecord& record = *pRecord;
            if (column == 0)
            {
                p = (void*)&treeItem; // because createIndex() wants void* a 3rd parameter
            }
            else
            {
                const QList<QVariant>& fieldList = record.fieldList;
                if (column <= fieldList.size())
                {
                    const QVariant* pField = &(fieldList[column - 1]); // -1 Because we have extra column at left side
                    if ( (QMetaType::Type)(pField->type()) == QMetaType::QString )
                    {
                        //const QString *pString = static_cast<const QString*>(pField->data());
                        p = const_cast<void*>(pField->data());
                    }
                    if ( (QMetaType::Type)(pField->type()) == QMetaType::QStringList )
                    {
                        const QStringList *pStringList = static_cast<const QStringList*>(pField->data());
                        //const QString *pString =  &(pStringList->at(0)) ;
                        p = const_cast<void*>( static_cast<const void*>( &(pStringList->at(0)) ) );
                    }
                }
            }
        }

        //qDebug() << "Creating index: " << row << ", " << column << ", " << p;
        return createIndex(row, column, p);
    }

    if (0 != column)
    {
        //qDebug() << "Creating index: " << row << ", " << column << ", 0 -- if (0 != column)";
        return createIndex(row, column, (void*)0);
    }

    p = parent.internalPointer();

    const TreeItem* pTreeItem = (const TreeItem*)p;
    if (0 == pTreeItem)
    {
        //qDebug() << "Creating index: " << row << ", " << column << ", 0 -- if (0 == pTreeItem)";
        return createIndex(row, column, (void*)0);
    }

    if (row < pTreeItem->m_Children.size())
    {
        const TreeItem* pTreeSubItem = pTreeItem->m_Children.at(row).data();
        //qDebug() << "Creating subline index: " << row << ", " << column << ", " << (void*)pTreeSubItem << "parent: " << pTreeItem;
        return createIndex(row, column, (void*)pTreeSubItem);
    }

    //qDebug() << "Creating index: " << row << ", " << column << ", 0";
    return createIndex(row, column, (void*)0);
}

QModelIndex Model_Tree::parent(const QModelIndex &index) const
{
    if (!index.isValid())
    {
        QModelIndex qi;
        qDebug() << "Creating INVACHILD PARENT index: " << qi.row() << ", " << qi.column() << ", " << 0;
        return qi;
    }

    const TreeItem* pChildItem = static_cast<const TreeItem*>(index.internalPointer());
    if (0 == pChildItem)
    {
        QModelIndex qi;
        qDebug() << "Creating NOTREEITEM PARENT index: " << qi.row() << ", " << qi.column() << ", " << 0;
        return qi;
    }

    const TreeItem* pParentItem = pChildItem->m_pParent;
    if (0 == pParentItem)
    {
        QModelIndex qi;
        qDebug() << "Creating NOPARENT PARENT index: " << qi.row() << ", " << qi.column() << ", " << 0;
        return qi;
    }

    qDebug() << "Creating PARENT index: " << pChildItem->m_RecordNumber << ", " << 0 << ", " << pParentItem;
    return createIndex(pParentItem->m_RecordNumber, 0, (void*)pParentItem);
}

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

    switch (role)
    {
    case Qt::TextAlignmentRole:
        return Qt::AlignTop;
    case Qt::DisplayRole:
        void* pInternal = index.internalPointer();
        int column = index.column();
        int row = index.row();

        if (0 == column)
        qDebug() << "Qt::DisplayRole for row " << row << ",column " << column << "pointer" << pInternal << "parent=" << index.parent().internalPointer();

        if (0 == pInternal)
        {
            //qDebug() << "DR: internal pointer is 0";
            return QVariant();
        }

        if (0 == column)
        {
            const TreeItem* pTreeItem = static_cast<const TreeItem*>(pInternal);

            QString displayString;
            QTextStream(&displayString) << pTreeItem->m_LogLineNumber;

            if (pTreeItem->m_type == TreeItem::Subline)
            {
                QTextStream(&displayString) << " (" << row << "-th sub-line)"
                                            << " " << (*(pTreeItem->m_pSubline));
            }
            if (pTreeItem->m_type == TreeItem::Record)
            {
                if (pTreeItem->m_Children.size() > 0)
                {
                    QTextStream(&displayString) << " (" << rowCount(index)/*pTreeItem->m_Children.size()*/ << " sub-lines)";
                }
            }
            return displayString;
        }

        // for columns other than 0 index contains QString* as internal pointer
        const QString* pText = static_cast<const QString*>(pInternal);
        return *pText;
    }

    return QVariant();
}

ここに画像の説明を入力

4

1 に答える 1

0

私を助けてくれてありがとうマレク!

問題は、サブアイテムを考慮していない QSortFilterProxyModel 派生クラスにありました)))

于 2013-07-30T17:54:48.583 に答える