[Qt-interest] Problem with subclassing of the QAbstractTableModel

Igor Mironchik imironchick at gmail.com
Fri Nov 5 15:08:55 CET 2010


Hi.

I've subclassed QAbstractTableModel to show 2 columns. And I want first 
column to be not editable and second - editable. Here is my flags() method:

Qt::ItemFlags flags( const QModelIndex & index ) const
    {
        qDebug() << "flags";
        if( !index.isValid() )
            return Qt::ItemIsEnabled;

        if( index.column() == 1 )
            return Qt::ItemIsEditable | Qt::ItemIsSelectable |
                Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
        else
            return Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |
                Qt::ItemIsEnabled;
    }

All is OK. But when I double clicked item in the first column in the 
QTreeView with my model and my application crashed with cycleing calls 
of the rowCount() and columnCount() methods.

Here is full code of my model:

//! Model for viewing correspondencies.
class CorrespondenceModel
    :    public QAbstractTableModel
{
public:
    CorrespondenceModel( QObject * parent = 0 )
        :    QAbstractTableModel( parent )
    {
    }

    int rowCount( const QModelIndex & parent = QModelIndex() ) const
    {
        qDebug() << "rowCount" << m_data.size();
        Q_UNUSED( parent );
        return m_data.size();
    }

    int columnCount( const QModelIndex & parent = QModelIndex() ) const
    {
        qDebug() << "columnCount";
        Q_UNUSED( parent );
        return 2;
    }

    QVariant data( const QModelIndex & index , int role ) const
    {
        qDebug() << "data";
        if( !index.isValid() )
            return QVariant();

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

        if( role == Qt::DisplayRole )
        {
            QPair< QString, QString > pair = m_data.at( index.row() );

            if( index.column() == 0 )
                return pair.first;
            else if( index.column() == 1 )
                return pair.second;
        }

        return QVariant();
    }

    QVariant headerData( int section, Qt::Orientation orientation, int 
role ) const
    {
        if( role != Qt::DisplayRole )
            return QVariant();

        if( orientation == Qt::Horizontal )
        {
            switch( section )
            {
                case 0:
                    return tr( "Excel file" );

                case 1:
                    return tr( "Format" );

                default:
                    return QVariant();
            }
        }

        return QVariant();
    }

    Qt::ItemFlags flags( const QModelIndex & index ) const
    {
        qDebug() << "flags";
        if( !index.isValid() )
            return Qt::ItemIsEnabled;

        if( index.column() == 1 )
            return Qt::ItemIsEditable | Qt::ItemIsSelectable |
                Qt::ItemIsUserCheckable | Qt::ItemIsEnabled;
        else
            return Qt::ItemIsSelectable | Qt::ItemIsUserCheckable |
                Qt::ItemIsEnabled;
    }

    bool setData( const QModelIndex & index, const QVariant & value,
        int role = Qt::EditRole )
    {
        qDebug() << "setData";
        if( index.isValid() && role == Qt::EditRole )
        {
            int row = index.row();

            QPair< QString, QString > p = m_data.value( row );

            if( index.column() == 0 )
                p.first = value.toString();
            else if( index.column() == 1 )
                p.second = value.toString();
            else
                return false;

            m_data.replace( row, p );

            emit dataChanged( index, index );

            return true;
        }

        return false;
    }

    bool insertRows( int position, int rows,
        const QModelIndex & index = QModelIndex() )
    {
        qDebug() << "insertRows";
        Q_UNUSED( index );

        beginInsertRows( QModelIndex(), position, position + rows - 1 );

        for (int row = 0; row < rows; ++row )
        {
            QPair< QString, QString > pair( "", "" );
            m_data.insert( position, pair );
        }

        endInsertRows();

        return true;
    }

    bool removeRows( int position, int rows,
        const QModelIndex & index = QModelIndex() )
    {
        qDebug() << "removeRows";
        Q_UNUSED( index );

        beginRemoveRows( QModelIndex(), position, position + rows - 1 );

        for( int row = 0; row < rows; ++row )
        {
            m_data.removeAt( position );
        }

        endRemoveRows();

        return true;
    }

    void insertRow( const QString & excelFile,
        const QString & format )
    {
        qDebug() << "insertRow";
        insertRows( 0, 1 );

        setData( index( 0, 0 ), excelFile );
        setData( index( 0, 1 ), format );
    }

    QString excelFile( int row ) const
    {
        return m_data.at( row ).first;
    }

    QString format( int row ) const
    {
        return m_data.at( row ).second;
    }

private:
    //! Data of the model.
    QList< QPair< QString, QString > > m_data;
}; // class CorrespondenceModel

Any idea?



More information about the Qt-interest-old mailing list