MVC problem



  • Hi to all!

    I am trying to import selected *.mp3 file names (I selected them via QFileDialog) into QTreeView and once I select them, the filenames do not show in QTreeView. Here is chunk of code:

    @
    void MainWindow::loadDir()
    {
    QStringList SelectedMP3s=QFileDialog::getOpenFileNames(this,
    tr("Selected mp3 files"),
    "..",
    "*.mp3");

    qDebug() << "Number of selected mp3 files:" << SelectedMP3s.size();
    

    // quint64 iRow=0;

    for(quint64 iIndex=0; iIndex<(quint64)SelectedMP3s.size(); iIndex++)
        this->listFileNames().append(new BSPPlayListItem(iIndex,
                                                         SelectedMP3s.at(iIndex),
                                                         QString("C:/Users/Public/Music/Sample Music/1973 Komandant Sava ; Konjuh planinom front.jpg"),
                                                         QTime(0, 0, 5, 0),
                                                         0));
    this->centralWidget()->playList()->model()->insertRows(0,
                                                           this->listFileNames().size()-1,
                                                           /*this->centralWidget()->playList()->model()->index(0, 0)*/
                                                           QModelIndex());
    

    }
    @

    The method loadDir is slot that correctly gets executed once I select files from QFileDialog. Can someone help me please?

    Sincerely,
    Marko

    [EDIT: code formatting, Volker]



  • You do insert rows but do not populate them with actual data.



  • How do i populate data? I am rather newbie at MVC and therefore I have huge problems ...



  • You can find a quite detailed introduction in the "Model/View Programming":http://doc.qt.nokia.com/latest/model-view-programming.html of the Qt docs.



  • Look, I've read that f..... detailed introduction and it is written awfully and I am catching deadline, is it maybe an error in subclassed insertRows method:
    @
    bool BSPPlayListModel::insertRows(int row,
    int count,
    const QModelIndex& parent)
    {
    if(!this->rootItem())
    this->setRootItem(new BSPPlayListItem());

    this->beginInsertRows(parent,
                          row,
                          row+count-1);
    for(quint64 iIndex=0; iIndex<(quint64)count; iIndex++)
        (void)new BSPPlayListItem();
    endInsertRows();
    
    return true;
    

    }@

    I am sooooooooo nervous .....



  • How did you implement the BSPPlayListModel::data() function?



  • Here is my implementation of data method:
    @
    QVariant BSPPlayListModel::data(const QModelIndex &index, int role) const
    {
    if(!this->rootItem() || !index.isValid() || index.column()<0 || index.column()>=(int)NR_COLUMNS)
    return QVariant();
    if(BSPPlayListItem* item=this->itemForIndex(index))
    {
    if(role==Qt::DisplayRole)
    {
    switch(index.column())
    {
    case BSP::ColumnName::COLUMN_NUMBER: return QString::number(item->number());
    case BSP::ColumnName::COLUMN_NAME: return item->name();
    case BSP::ColumnName::COLUMN_DURATION: return item->duration().toString();
    default: Q_ASSERT(false);
    }
    }
    if(role==Qt::DecorationRole)
    {
    switch(index.column())
    case BSP::ColumnName::COLUMN_ALBUM_ART: return QPixmap(item->thumbnailPath());
    }
    }
    return QVariant();
    }
    @
    And why my code in this post is not formatted? I've pressed "CODE" button ...



  • Put a newline behind your @ symbols.



  • Hmm, I've set breakpoint and this method never gets called. Is this reason of all my problems?



  • Might be a good indicator, yes. Do your rowCount() and columnCount() methods return sensible results?



  • Yes, they do, but now I've noticed I do not have reimplemented setData method. Let me try to reimplement it ... will post results ...



  • setData() is not really necessary if you don't allow external editing.

    What does this code portion do?
    [quote author="MarkoSiroki" date="1298526272"]
    @
    bool BSPPlayListModel::insertRows(int row,
    int count,
    const QModelIndex& parent)
    {
    //...
    for(quint64 iIndex=0; iIndex<(quint64)count; iIndex++)
    (void)new BSPPlayListItem();
    //...
    }@
    [/quote]
    More specifically, what happens with the new BSPPlayListItem?



  • Franzk is right: if you only need viewing capabilities, then you don't need to reimplement any of the editing methods. That includes insertRows(), insertColumns and setData().

    Of course, you still need your own methods to tell the model that new data has arrived, but you can design that to your own liking.

    Could you tell us what data structure you use to store the data on your mp3's?

    Also: if this is your first QAbstractItemModel, you've picked the most tricky one to start with: a tree model. Those are simply not so easy to work with.



  • If insertRows() is called from outside the model, then setData() is also needed.



  • And yet another introduction into MVC is the "Model/View Tutorial ":http://doc.qt.nokia.com/4.7/modelview.html of the docs.



  • If you really do not need a tree structure, use simply QAbstractTableModel and implement data(), rowCount(), coulnCount() and headerData() functions. They are really easy for you if you have not worked with complex models.



  • Well, here is code for item:
    @
    #ifndef BSPPLAYLISTITEM_H
    #define BSPPLAYLISTITEM_H

    #include <QObject>
    #include <QtCore/QString>
    #include <QtCore/QList>
    #include <QtCore/QTime>

    class BSPPlayListItem : public QObject
    {
    Q_OBJECT

    public:
    explicit BSPPlayListItem(QObject parent = 0);
    BSPPlayListItem(const quint64 iId/
    =0*/,
    const QString& name/=QString()/,
    const QString& thumbnailPath/=QString()/,
    const QTime& length/=QTime()/,
    BSPPlayListItem* pParent/=0/);
    ~BSPPlayListItem();

    inline quint64& number()
        { return m_iNumber; }
    inline void setNumber(const quint64& id)
        { m_iNumber=id; }
    inline QString& name()
        { return m_strName; }
    inline void setName(const QString& name)
        { m_strName=name; }
    inline QString& thumbnailPath()
        { return m_strThumbnailPath; }
    
    inline QTime& duration()
        { return m_tmLength; }
    inline void setDuration(const QTime& duration)
        { m_tmLength=duration; }
    inline void setThumbPath(const QString& path)
        { m_strThumbnailPath=path; }
    
    inline BSPPlayListItem* parent()
        { return m_pParent; }
    inline BSPPlayListItem* childAt(const quint64& iRow) const
        { return m_lsChildren.value(iRow); }
    inline quint64 rowOfChild(BSPPlayListItem* const child) const
        { return m_lsChildren.indexOf(child); }
    inline bool hasChildren() const
        { return !m_lsChildren.isEmpty(); }
    inline int childCount() const
        { return m_lsChildren.size(); }
    inline QList<BSPPlayListItem*>& children()
        { return m_lsChildren; }
    inline void insertChild(const quint64& iRow,
                            BSPPlayListItem* const item)
        { item->m_pParent=this; m_lsChildren.insert(iRow, item); }
    inline void addChild(BSPPlayListItem* const item)
        { item->m_pParent=this; m_lsChildren << item; }
    inline void swapChildren(const quint64& iOldRow,
                             const quint64& iNewRow)
        { m_lsChildren.swap(iOldRow, iNewRow); }
    BSPPlayListItem* takeChild(const quint64& iRow);
    

    private:
    quint64 m_iNumber;
    QString m_strName;
    QString m_strThumbnailPath;
    QTime m_tmLength;

    BSPPlayListItem* m_pParent;
    QList<BSPPlayListItem*> m_lsChildren;
    

    };

    #endif // BSPPLAYLISTITEM_H
    @

    and cpp file:
    @
    #include "BSPPlayListItem.h"

    BSPPlayListItem::BSPPlayListItem(QObject *parent)
    : QObject(parent),
    m_strName(QString()),
    m_strThumbnailPath(QString()),
    m_tmLength(QTime()),
    m_pParent(0)
    {
    this->m_lsChildren.clear();
    }

    BSPPlayListItem::BSPPlayListItem(const quint64 iId,
    const QString& name,
    const QString& thumbnailPath,
    const QTime& length,
    BSPPlayListItem* pParent)
    : m_iNumber(iId),
    m_strName(name),
    m_strThumbnailPath(thumbnailPath),
    m_tmLength(length),
    m_pParent(pParent)
    {
    if(m_pParent)
    m_pParent->addChild(this);
    }

    BSPPlayListItem::~BSPPlayListItem()
    {
    qDeleteAll(m_lsChildren);
    }

    BSPPlayListItem* BSPPlayListItem::takeChild(const quint64& iRow)
    {
    BSPPlayListItem* item=this->m_lsChildren.takeAt(iRow);
    item->m_pParent=0;

    return item;
    

    }
    @

    The point is I must make Media Playlist like in MediaMonkey or Apple iTunes and because to sort albums alphabeticly, I thought to use QTreeView for albums and then inside each album a table of songs. This table of songs must be resizable.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.