Q:

AbstractListModel with two columns, how to choose which column to show in ListView?

I have subclassed QAbstractListModel with two columns, something like:
class MediaList : public QAbstractListModel {

public:
    QVariant data(QModelIndex const& index, int role) const override
    {
        if (index.column() == 0)
            return QVariant(m_songs.at(index.row()));
        if (index.column() == 1)
            return QVariant(m_videos.at(index.row()));
        return QVariant();
    }

    int rowCount(QModelIndex const& parent = QModelIndex()) const override
    {
        return m_videos.size() < m_songs.size() ? m_songs.size() : m_videos.size();
    }

private:
    QStringList m_songs;
    QStringList m_videos;
};

Obviously there's more to it, but that's the main idea. I then expose it to QML via Qt's context feature. Now in QML I have something like this:
ListView {
    model: myMediaList
    delegate: Text {
        text: modelData
    }
}

And it properly shows the "songs" as a list of text rows. But how do I tell it to use the column 1 instead, so I could see the "videos" instead?

A:

I think QAbstractListModel is not meant to have more than one column:

The QAbstractListModel class provides an abstract model that can be subclassed to create one-dimensional list models.
[...]
Since the model represents a one-dimensional structure, the rowCount() function returns the total number of items in the model. The columnCount() function is implemented for interoperability with all kinds of views, but by default informs views that the model contains only one column.

https://doc.qt.io/qt-5/qabstractlistmodel.html#details
You can use model roles instead:
// In MediaList's header:
enum MediaListRole {
    SongRole = Qt::UserRole,
    VideoRole
};

// ...    

QVariant data(QModelIndex const& index, int role) const override
{
    if (role == SongRole)
        return QVariant(m_songs.at(index.row()));
    else if (role == VideoRole)
        return QVariant(m_videos.at(index.row()));
    return QVariant();
}

QHash<int, QByteArray> roleNames() const
{
    QHash<int, QByteArray> names;
    names.insert(SongRole, "song");
    names.insert(VideoRole, "video");
    return names;
}

Then, in QML:
delegate: Text {
    text: model.song
}

