Listview delgate signal and C++
-
I'm a bit confused about how to emit a signal when I click on a listview item.
I read that if I set an object name in the delegate then with findchid() I will get all items in the list.
I think that the best way is to make a mousearea in the delegate and in its onlicked set listview current index to the clicked delegate index and at the end read the current index with C++.
But I've the delegate in a .qml file and the listview in an other qml file, and I set the delegate in this way:
@delegate: myQmlDelegateFile{}@
In this case how can I set the listview current index to clicked index?Anyhow which is the best way to capture the item click event in C++ and the clicked item? Thanks very much
Regards Andrea
-
There's really not enough info in your question for a quick answer. So here's a long one.
I'm not a big fan of having C++ reach down into my QML using object names. I much prefer to just use the setContextProperty() call to give my QML access to a "View Manager" class. That class would have all the Q_PROPERTY's I need. So assuming you have a Q_PROPERTY named currentIndex on your C++ class with all the appropriate getters, setters and notify. In your row onclicked handler you could just add
@MainViewMgr.currentIndex = index@
I'm not quite sure what your question is about having your delegate in a separate file but if your mouse area is also in the file it shouldn't be a problem. Here's a sample QML delegate file with a mouse area that's setting the current index. (This is just a cut and paste of some sample code from Qt Quick course so it's not all relevant).
@
import QtQuick 2.3Item{
id: rowIdheight: dataRowId.implicitHeight width : dataRowId.implicitWidth Row{ id: dataRowId spacing : 10 Text{ text: index + ". " + model.name font.pixelSize : rowId.ListView.view.fontSize } Text{ text: category font.pixelSize: rowId.ListView.view.fontSize } } MouseArea{ anchors.fill: parent onClicked:{ rowId.ListView.view.currentIndex = index MainViewMgr.currentIndex = index } }
}
@In your startup code would be something along these lines
@
auto root_context = m_engine.rootContext();
root_context->setContextProperty("MainViewMgr",&m_mainViewMgr);@
And then in this sample the member variable m_mainViewMgr is a reference to a custom MainViewMgr class that in this case needs a single Q_PROPERTY named currentIndex. I use my "AUTO_PROPERTY macro":http://syncor.blogspot.com/2014/11/qt-auto-property.html so the class could be just this
@
class MainViewMgr : public QObject
{
Q_OBJECT
AUTO_PROPERTY(int, currentIndex)
public:
explicit MainViewMgr(QObject *parent=0);};
@
Hope that covers your question. My new course on using QML with C++ (to be published next month on Pluralsight) will cover this approach in detail although I don't use a list model in the demos.
-
Thank you very much for this perfect answer.
However I would like to use a solution like this:The delegate is composed by:
@Component{
id: song_Tab_DelegateRectangle { id: itemDelegate property string arg: Filename //sets by list model .... MouseArea { anchors.fill: parent onClicked: { song_Tab_Delegate.ListView.view.currentIndex = index }
.....
@
I've make a itemClick(string) signal in library_page, then in the listview i inserted
@onCurrentIndexChanged: {
if(currentIndex>=0)
library_page.itemClick(currentItem.itemDelegate.arg)
}@But it doesn't find currentItem.itemDelegate.
What is wrong?
Thanks a lot
Regards
AndreaEDIT: I've solved the issue was that I had to write currentItem.arg.
Well done for your book