How to get clicked item index of QScrollArea?
-
Hello. I have a problem. How can I get an index of item in QScrollArea?
This is my code:
QWidget *widget = new QWidget(); ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); ui->scrollArea->setWidgetResizable(true); ui->scrollArea->setWidget(widget); widget->setLayout(Vlayout);
I have some custom widgets added to QVBoxLayout:
Vlayout->addWidget(operationWidget);
Result:
And I would like to set each of my widget as checked (highlighted). So I decided to use event filter:
ui->scrollArea->viewport()->installEventFilter(this);
bool QueriesCreator::eventFilter(QObject *object, QEvent *event) { if(object == ui->scrollArea->viewport() && event->type()==QEvent::MouseButtonRelease) { QMouseEvent * mouseEvent = static_cast< QMouseEvent * >( event ); if( mouseEvent->button() == Qt::LeftButton ) { if(Vlayout->count()>0) { QWidget *widget = childAt(mouseEvent->pos()); int index = Vlayout->layout()->indexOf(widget); qDebug()<<index; if(index>=0) { QLayoutItem* const item = Vlayout->layout()->itemAt(index); auto widget = dynamic_cast<OperationWidget*>(item); } } return true; } else return false; } return false; }
And the index I get is -1. I don't know why. If you have any idea how to get index of clicked QScrollArea element. I will be very thankfull. Have a good day.
-
Hi,
You are likely getting one of the subwidget of your "items".
From the looks of it, using a QListView with a QStyledItemDelegate would be simpler and you would have the highlighting easier to handle.
-
@BushyAxis793 You're probably clicking on a sub widget, so indexOf will not find it. You can find your widget easier by going through the parents of what was clicked and avoiding the indexing and dynamic casts:
... QWidget *widget = childAt(mouseEvent->pos()); // go up parent chain until you find OperationWidget while(widget && !widget->metaObject()->inherits(&OperationWidget::staticMetaObject)) widget = widget->parentWidget(); if (widget) { OperationWidget* op = qobject_cast<OperationWidget*>(widget); // do something with op } else { // not found, probably clicked between widgets }
-
@Chris-Kawa said in How to get clicked item index of QScrollArea?:
!widget->metaObject()->inherits(&OperationWidget::staticMetaObject)
What's this bit Chris? I can guess this is how you recognise the root of the widget tree?
-
@JonB The loop is pretty much just "while widget is not OperationWidget check parent".
Thiswidget->metaObject()->inherits(&OperationWidget::staticMetaObject)
is pretty much the same as
dynamic_cast<OperationWidget*>(widget) != nullptr
just QObject specific. I guess you can also write that loop as
while (widget && !qobject_cast<OperationWidget*>(widget))
if you don't fancy the metaObject stuff directly (qobject_cast does that internally).
-
@Chris-Kawa said in How to get clicked item index of QScrollArea?:
widget->metaObject()->inherits(&OperationWidget::staticMetaObject)
or
widget->inherits("OperationWidget") -
@mpergand I have an acquired distaste for string based APIs, so I intentionally try not to mention them whenever I can :) But yeah, you could do that and then rename the class while forgetting to also change the string and wonder what's happening. To each their own :)
-
@Chris-Kawa said in How to get clicked item index of QScrollArea?:
I have an acquired distaste for string based APIs,
OK, cut the apple in two :)
widget->inherits(OperationWidget::staticMetaObject.className())Anyway, I don't see any reason for not using qobject_cast here.
-
@SGaist I supposed it too. However here: https://forum.qt.io/topic/142288/how-can-i-add-custom-widget-to-qlistview/15
I tried to create model/view but without result. So I decided to looking for new ideas which would be good for me. All I want is some features:
- Highlight my widget
- Double clik on my widget
- Change order (move up/down) of my witgets list
I hope I will find solution.
-
You do realize that you are trying to reimplement the model/view paradigm rather than implementing a delegate that should paint three strings ?