PDA

View Full Version : model/view setData help



nategoofs
17th August 2007, 06:29
What I'm trying to do is use a combobox to change the data in a reimplemented QAbstractTableModel that is shown through a QTableView. I have the data function as follows:


QVariant WTrackTableModel :: data(const QModelIndex &index, int role) const
{
TrackInfoObject *m_pTrackInfo = m_pTrackCollection->getTrack(index.row()+1);
if (!index.isValid())
return QVariant();

if (index.row() >= m_pTrackCollection->getSize())
return QVariant();

if (role == Qt::BackgroundRole)
{
return backgroundColor;
}
//if (role == Qt::ForegroundRole )
//{
//return foregroundColor;
//}
else if (role == Qt::DisplayRole )
{
switch(index.column())
{
case 0: return m_pTrackInfo->getScoreStr();
case 1: return m_pTrackInfo->getTitle();
case 2: return m_pTrackInfo->getArtist();
case 3: return m_pTrackInfo->getType();
case 4: return m_pTrackInfo->getDurationStr();
case 5: return m_pTrackInfo->getBitrateStr();
case 6: return m_pTrackInfo->getBpmStr();
case 7: return m_pTrackInfo->getComment();
}
}

else
return QVariant();
}


I know that maybe a setData reimplementation might do this model some good but I don't understand how I would use it. I also know that to change the data in my table I think i would need to emit the dataChanged function....although I dont know where to emit it and when. I have a separate function in another class that handles the combobox change:


connect(m_pView->m_pComboBox, SIGNAL(activated(int)), this, SLOT(slotActivatePlaylist(int)));

void Track::slotActivatePlaylist(int index)
{
if (m_pActivePlaylist)
m_pActivePlaylist->deactivate();

// Insert playlist according to ComboBox index
m_pActivePlaylist = m_qPlaylists.at(index);
m_pActivePlaylist->activate(m_pView->m_pTrackTable);
//m_pTableModel->setTrackCollection(m_pActivePlaylist->getCollection());
}


Although, I can't really figure out what to do for the QTableView or QAbstractTableModel Item data update.
Any suggestions on how I should proceed?

Thanks!

jpn
17th August 2007, 09:23
I suggest you take a look at the spinbox delegate example (http://doc.trolltech.com/4.3/itemviews-spinboxdelegate.html) to see how to properly provide custom editors (that is a combobox for you). When you do so, you end up calling model's setData() properly as well. ;)

nategoofs
17th August 2007, 18:25
I'm sorry, I suppose I wasn't clear enough. The combobox rests outside of the model/view entirely and acts as a "view control" to the model/view. Meaning, say the combobox goes from a "Music library" view to a "Play Queue" view, the model should adjust accordingly, given the information from an outside source. My main beef is that I do not know how I would use setData when the View realizes that the information on the model has changed.

wysota
17th August 2007, 18:34
I'm not entirely sure what you are trying to do, but I think "Music library" and "Play Queue" should be separate views handled inside QStackedWidget. And setData() method of the model doesn't have anything to do with any of the views... It's used for modifying the data behind the model.

nategoofs
17th August 2007, 18:47
that's exactly what I'm trying to do - modify the data of the model. When the comboBox is activated it shouldn't simply switch a view, the data inside the model should be adjusted accordingly. The information needed is already set aside in a "trackcollection" class which simply holds a list of sorts as to what tracks belong to each list view(i.e Library and PlayQueue respectively).

Sorry if Im not being that clear!...It's a confusing problem :p

wysota
17th August 2007, 19:35
that's exactly what I'm trying to do - modify the data of the model. When the comboBox is activated it shouldn't simply switch a view, the data inside the model should be adjusted accordingly.
I don't think so. I think the view should just display different data. QAbstractItemView::setRootIndex() might be what you're looking for. You can use it with conjunction with a hierarchical (tree-like) model to switch between sets of data the view is displaying. Just like switching between directories in QDirModel - the model doesn't change here, it's the view that does.

nategoofs
18th August 2007, 11:21
After much pondering and racking of my brain to understand this, I think you're right. SO then if I have two separate lists of data, each needing to be displayed when the combobox changes to its respective selection, what then will I need to do if I simply want to swap the information? Can I just make two different models and swap models accordingly with setModel on the QTableView when the combobox selection changes? If not, what would be another way to accomplish this....I would rather not use another view since I need only the table view to show on my app.

Thanks!

jpn
18th August 2007, 11:53
Yes, either build two separate models and switch between them by using QAbstractItemView::setModel() or embed both lists to same model and use QAbstractItemView::setRootIndex() as wysota suggested. Both methods work with a single view.

wysota
18th August 2007, 13:23
I would rather not use another view since I need only the table view to show on my app.

If you use a QStackedWidget, only one view will be visible at a given time. The advantage would be that the view wouldn't have to reinitialize itself every time you select an item in the combobox.

nategoofs
18th August 2007, 14:19
would there be a reason why my ContextMenuEvent would cause my app to crash if I had two models for one view? I just separated the info into two models and that is what's happening.

wysota
18th August 2007, 15:05
Yes, it's possible :) Try debugging and see where the crash occurs. You might be referring to an invalid index or something like that.

nategoofs
18th August 2007, 22:46
I've tried debugging, and it looks like a get the inValid data around here:


void WTrackTableView :: contextMenuEvent(QContextMenuEvent * event)
{
index = indexAt(event->pos());
m_pTrackInfoObject = m_pTable->m_pTrackPlaylist->getTrackAt(index.row()+1);
if(index.isValid())
{
QMenu menu(this);
menu.addAction(PlayQueueAct);
if (ControlObject::getControl(ConfigKey("[Channel1]","play"))->get()!=1.)
menu.addAction(Player1Act);
if (ControlObject::getControl(ConfigKey("[Channel2]","play"))->get()!=1.)
menu.addAction(Player2Act);
menu.addAction(RemoveAct);
menu.exec(event->globalPos());
}
}

on line 5 in the getTrackAt function. I can't understand why however since when I debugged it, it was returning a valid number, nothing high or anything...and it was the number of the row that I selected. what the getTrackAt function does is:


TrackInfoObject *TrackPlaylist::getTrackAt(int index)
{
return m_qList.at(index);
}

where m_qList is a Q3PtrList<TrackInfoObject> type list. Am I doing something wrong that I'm just not seeing...or has the fact that I have two models now somehow messed up my chances of using contextMenuEvent? I mean it doesn't make any sense that it would be the case since the model is set to the view right?

wysota
18th August 2007, 23:04
It's hard to say without more info. What does the backtrace say?

nategoofs
19th August 2007, 01:46
I actually only did some manual debugging with qdebug and checking values. Im not sure what you mean by backtrace...I dont normally use the debugger on MSVC and when I try nothing really gets solved. What sort of information were you looking for?

jpn
19th August 2007, 07:46
The contents of "Debug->Windows->Call Stack" by the time of a crash.

nategoofs
19th August 2007, 17:38
call stack Info:

Qt3Support4.dll!600063d8()
[Frames below may be incorrect and/or missing, no symbols loaded for Qt3Support4.dll]
Qt3Support4.dll!6001ee5a()
mixxx.exe!Q3PtrList<TrackInfoObject>::at() + 0x14 bytes
mixxx.exe!TrackPlaylist::getTrackAt() + 0x16 bytes
mixxx.exe!WTrackTableView::contextMenuEvent() + 0x7c bytes
QtGui4.dll!65049447()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
gdi32.dll!77f17012()
gdi32.dll!77f16ffa()
ntdll.dll!7c910732()
QtGui4.dll!65258775()
QtGui4.dll!652b686e()
QtGui4.dll!6530f773()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
gdi32.dll!77f17012()
gdi32.dll!77f16ffa()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c91056d()
QtGui4.dll!65118dcd()
QtGui4.dll!65118de9()
QtGui4.dll!65118e00()
ntdll.dll!7c91056d()
msvcr80.dll!78134c39()
msvcr80.dll!78134c58()
msvcr80.dll!78134d83()
QtGui4.dll!6521bbdc()
QtCore4.dll!67009294()
QtGui4.dll!652b66c1()
QtGui4.dll!650132f7()
QtGui4.dll!65015cce()
RTSUltraMonHook.dll!1880777c()
RTSUltraMonHook.dll!18807781()
ntdll.dll!7c910551()
QtGui4.dll!65116096()
user32.dll!7e41f84a()
user32.dll!7e4563be()
user32.dll!7e41b50c()
user32.dll!7e41b51c()
ntdll.dll!7c90eae3()
user32.dll!7e4194be()
user32.dll!7e442135()
RTSUltraMonHook.dll!188078e6()
user32.dll!7e41882a()
user32.dll!7e41b4c0()
user32.dll!7e41f84a()
QtCore4.dll!67005c29()
QtCore4.dll!6709ecb0()
QtCore4.dll!670c8072()
QtGui4.dll!6505392d()
msvcr80.dll!78134c58()
QtGui4.dll!65055436()
QtGui4.dll!6510f284()
ntdll.dll!7c910732()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
QtGui4.dll!650c20a9()
QtGui4.dll!650c20b2()
QtGui4.dll!650eee11()
QtGui4.dll!650f90d2()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
QtGui4.dll!650ac7af()
QtGui4.dll!650d02d6()
QtGui4.dll!650eee11()
QtGui4.dll!650fc82d()
QtGui4.dll!650fcdcc()
QtGui4.dll!650bc28c()
QtGui4.dll!6510f284()
QtGui4.dll!6507056d()
QtGui4.dll!650f44f2()
QtGui4.dll!650c20a9()
QtGui4.dll!650c20b2()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
atioglxx.dll!6915b5ad()
atioglxx.dll!6915b5ef()
ntdll.dll!7c91056d()
msvcr80.dll!78134c39()
ntdll.dll!7c91056d()
msvcr80.dll!78134c39()
ntdll.dll!7c91056d()
msvcr80.dll!78134c39()
msvcr80.dll!78134c58()
msvcr80.dll!78134c58()
QtGui4.dll!650bc8d5()
msvcr80.dll!78134c58()
QtGui4.dll!650c3111()
QtGui4.dll!650c3195()
mixxx.exe!WSliderComposed::paintEvent() + 0xd5 bytes
QtGui4.dll!650493e4()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
QtGui4.dll!6521bbdc()
mixxx.exe!MixxxKeyboard::eventFilter() + 0x7e bytes
QtGui4.dll!65013340()
QtGui4.dll!65016218()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
user32.dll!7e418cc3()
user32.dll!7e419ef0()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c915041()
ntdll.dll!7c915233()
ntdll.dll!7c9155c9()
ntdll.dll!7c915152()
ntdll.dll!7c91554a()
ntdll.dll!7c9153f5()
ntdll.dll!7c915d7d()
ntdll.dll!7c915db4()
ntdll.dll!7c915041()
ntdll.dll!7c915233()
ntdll.dll!7c9155c9()
ntdll.dll!7c915152()
ntdll.dll!7c91554a()
ntdll.dll!7c9153f5()
gdi32.dll!77f1c5ac()
gdi32.dll!77f1c58c()
gdi32.dll!77f1c3f5()
gdi32.dll!77f1c597()
ntdll.dll!7c915d7d()
gdi32.dll!77f17f7c()
gdi32.dll!77f1840c()
gdi32.dll!77f18c7c()
ntdll.dll!7c915041()
ntdll.dll!7c915233()
gdi32.dll!77f1c5ac()
gdi32.dll!77f1c5ac()
gdi32.dll!77f1c5ac()
gdi32.dll!77f1c58c()
gdi32.dll!77f1c597()
gdi32.dll!77f1c5ac()
gdi32.dll!77f1c58c()
gdi32.dll!77f1c597()
gdi32.dll!77f1c597()
gdi32.dll!77f1c3f5()
gdi32.dll!77f1c597()
gdi32.dll!77f1c5ac()
gdi32.dll!77f1c58c()
gdi32.dll!77f1c597()
ntdll.dll!7c915233()
atioglxx.dll!692fe5b1()
atioglxx.dll!693021db()
atioglxx.dll!6912e59a()
atioglxx.dll!6912da26()
atioglxx.dll!6932f0ca()
atioglxx.dll!692fec94()
atioglxx.dll!692fadda()
atioglxx.dll!6912dfb6()
atioglxx.dll!6930fcf0()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c91440e()
atioglxx.dll!6932ed93()
atioglxx.dll!6919f798()
atioglxx.dll!690e96cd()
ntdll.dll!7c917326()
ntdll.dll!7c917304()
atioglxx.dll!6930fab5()
atioglxx.dll!6930fae3()
atioglxx.dll!693034e6()
atioglxx.dll!69303961()
atioglxx.dll!69303a88()
atioglxx.dll!692ed3c4()
opengl32.dll!5ed1c506()
opengl32.dll!5ed26710()
ntdll.dll!7c917304()
kernel32.dll!7c80abf7()
gdi32.dll!77f45684()
QtOpenGL4.dll!6301a749()
mixxx.exe!WVisualWaveform::timerEvent() + 0x2f bytes
QtCore4.dll!670ae58e()
QtCore4.dll!670dd293()
QtGui4.dll!65049976()
uxtheme.dll!5ad7153d()
QtGui4.dll!6521bbdc()
QtOpenGL4.dll!6301ab5a()
QtGui4.dll!65013340()
QtGui4.dll!65016218()
RTSUltraMonHook.dll!188021e0()
gdi32.dll!77f15a0e()
user32.dll!7e4184b2()
user32.dll!7e4186be()
RTSUltraMonHook.dll!18802142()
QtCore4.dll!67005c29()
mixxx.exe!ControlObjectThread::valueChanged() + 0x2b bytes
mixxx.exe!ControlObjectThreadMain::eventFilter() + 0x59 bytes
QtGui4.dll!650132f7()
QtGui4.dll!65016218()
RTSUltraMonHook.dll!18807781()
user32.dll!7e41f896()
RTSUltraMonHook.dll!18807781()
user32.dll!7e41f84a()
user32.dll!7e4563be()
QtCore4.dll!6709ecb0()
QtCore4.dll!6709ed13()
QtCore4.dll!670bafe7()
user32.dll!7e41f896()
RTSUltraMonHook.dll!18807b7d()
RTSUltraMonHook.dll!18807b82()
RTSUltraMonHook.dll!18807b82()
user32.dll!7e41f84a()
user32.dll!7e418734()
user32.dll!7e418816()
user32.dll!7e4189cd()
user32.dll!7e419402()
user32.dll!7e418a10()
QtCore4.dll!670bcee2()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
QtCore4.dll!6702cc30()
gdi32.dll!77f176bb()
msvcr80.dll!78134c58()
QtGui4.dll!65116342()
QtGui4.dll!6511978e()
msvcr80.dll!781323ff()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
QtOpenGL4.dll!6301e11b()
QtGui4.dll!65119e26()
QtGui4.dll!65119e59()
ntdll.dll!7c91056d()
msvcr80.dll!78134c39()
msvcr80.dll!78134c58()
gdi32.dll!77f176bb()
msvcr80.dll!78134c58()
QtGui4.dll!65116342()
QtGui4.dll!65051a22()
QtGui4.dll!65051a6b()
QtGui4.dll!650554a8()
QtGui4.dll!6505508b()
user32.dll!7e4194be()
user32.dll!7e41b42d()
gdi32.dll!77f176bb()
user32.dll!7e41b3f9()
user32.dll!7e418bd9()
user32.dll!7e41b3cc()
user32.dll!7e41b3a7()
user32.dll!7e41b3a7()
QtGui4.dll!6537cd5b()
QtGui4.dll!650554d1()
QtGui4.dll!650554e5()
ntdll.dll!7c917bb0()
usp10.dll!74da9a58()
usp10.dll!74da9d63()
ntdll.dll!7c917bb0()
msvcr80.dll!781352f6()
msvcr80.dll!7813532d()
msvcr80.dll!7813532d()
QtGui4.dll!6507e95d()
QtGui4.dll!65148974()
QtGui4.dll!65148f35()
QtGui4.dll!65148e8b()
ntdll.dll!7c910732()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c911596()
ntdll.dll!7c9106eb()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c9106eb()
ntdll.dll!7c9106eb()
msvcr80.dll!78134d83()
QtCore4.dll!67009294()
QtCore4.dll!670a0881()
ntdll.dll!7c9106eb()
msvcr80.dll!78134d83()
ntdll.dll!7c910732()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c910732()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c9106ab()
ntdll.dll!7c9106eb()
ntdll.dll!7c910732()
ntdll.dll!7c910732()
ntdll.dll!7c9106eb()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
QtGui4.dll!65213807()
ntdll.dll!7c9105c8()
ntdll.dll!7c910551()
ntdll.dll!7c91056d()
ntdll.dll!7c9106eb()
msvcr80.dll!78134d83()
ntdll.dll!7c91056d()
msvcr80.dll!78134c39()


it looks like the problem could be with my getTrackAt (index) function...but I don't understand why it worked before I added the other model...

nategoofs
19th August 2007, 18:00
i Found the problem! I failed to mention that I made another function to set a model to a proxymodel then used setModel( proxyModel) to the TableView without ever setting the m_pTable of the sent model...like so:


void WTrackTableView :: setSearchSource(WTrackTableModel *pSearchSourceModel)
{
m_pTable = pSearchSourceModel;
m_pSearchFilter->setSourceModel(pSearchSourceModel);
setModel(m_pSearchFilter);
}

It was something I didn't do before because I was only working with one model and set that model elsewhere. Thanks to all for your help!!