QSlider connect and C++ lambda ?
-
I have an Attribute class which subclass QGraphicsItem
Depending on the data type, I may create a QSlider associated with it or just a simple QLineEdit
I am attempting to connect the QSlider that is created within the Attribute class to connect with some method in the Attribute class
I am having difficult wrapping my head around the lambda approach for it.
Are we allow to call the connect method that is part of QSlider or must we call connect from a parent to perform the connection? Is self connection allowed ?
Attribute::Attribute(const std::string &name, bool labelOnRight, float x, float y, const std::string &type, const QFontMetrics *fontMetrics, QGraphicsItem *parent) :QGraphicsItem(parent) ,_width(attributeWidth) ,_height(attributeHeight) ,_radius(attributeRadius) ,_labelOnRight(labelOnRight) ,_label(name) ,_type(type) ,_fontMetrics(fontMetrics) ,_widget(nullptr) { // Set up the associated UI widget here so we can connect // up the action stuff at the same time if (_type.compare("string")==0) { _widget = attributeLineEditWidget(_label.c_str()); } else if (_type.compare("int")==0) { Range range; range.first.setValue<int>(0); range.second.setValue<int>(10); _widget = attributeSliderWidget(_label.c_str(),&range); // Register action QSlider *slider = _widget->findChild<QSlider *>(); slider->connect(slider, QSlider::SliderValueChange, this, [this]() {}); } // Do these before setPos() as the calculations will be off QRectF tightRect = fontMetrics->tightBoundingRect(name.c_str()); _labelRect = mapToParent(tightRect).boundingRect(); _pen.setWidth(1); // Try to do this last as it affects other calculations setPos(x, y); }
-
Answering my own post, I have found this to be working in case anyone else is looking for some answers.
My error was providing the wrong signal
QSlider *slider = _widget->findChild<QSlider *>(); slider->connect(slider, &QSlider::valueChanged, [this](int intValue) { printf("intValue = %d\n",intValue); });
-
I have an Attribute class which subclass QGraphicsItem
Depending on the data type, I may create a QSlider associated with it or just a simple QLineEdit
I am attempting to connect the QSlider that is created within the Attribute class to connect with some method in the Attribute class
I am having difficult wrapping my head around the lambda approach for it.
Are we allow to call the connect method that is part of QSlider or must we call connect from a parent to perform the connection? Is self connection allowed ?
Attribute::Attribute(const std::string &name, bool labelOnRight, float x, float y, const std::string &type, const QFontMetrics *fontMetrics, QGraphicsItem *parent) :QGraphicsItem(parent) ,_width(attributeWidth) ,_height(attributeHeight) ,_radius(attributeRadius) ,_labelOnRight(labelOnRight) ,_label(name) ,_type(type) ,_fontMetrics(fontMetrics) ,_widget(nullptr) { // Set up the associated UI widget here so we can connect // up the action stuff at the same time if (_type.compare("string")==0) { _widget = attributeLineEditWidget(_label.c_str()); } else if (_type.compare("int")==0) { Range range; range.first.setValue<int>(0); range.second.setValue<int>(10); _widget = attributeSliderWidget(_label.c_str(),&range); // Register action QSlider *slider = _widget->findChild<QSlider *>(); slider->connect(slider, QSlider::SliderValueChange, this, [this]() {}); } // Do these before setPos() as the calculations will be off QRectF tightRect = fontMetrics->tightBoundingRect(name.c_str()); _labelRect = mapToParent(tightRect).boundingRect(); _pen.setWidth(1); // Try to do this last as it affects other calculations setPos(x, y); }
Are we allow to call the connect method that is part of QSlider or must we call connect from a parent to perform the connection?
The member function
QObject::connect(...)
is just a convenience inline wrapper for the static one, so you can call it on any level of inheritance or directly the static one and it's all the same. The various overloads are there just for convenience, soslider->connect
,QSlider::connect
andQObject::connect
are all the same and you can call any of them to the same effect.Is self connection allowed ?
Yes, same object can be used as a sender and receiver.
slider->connect(slider, &QSlider::valueChanged, [this](int intValue)
Just a note here. Since you're not using
this
in the lambda you don't need to capture it. Don't make the optimizer's job harder than it needs to be. -
Are we allow to call the connect method that is part of QSlider or must we call connect from a parent to perform the connection?
The member function
QObject::connect(...)
is just a convenience inline wrapper for the static one, so you can call it on any level of inheritance or directly the static one and it's all the same. The various overloads are there just for convenience, soslider->connect
,QSlider::connect
andQObject::connect
are all the same and you can call any of them to the same effect.Is self connection allowed ?
Yes, same object can be used as a sender and receiver.
slider->connect(slider, &QSlider::valueChanged, [this](int intValue)
Just a note here. Since you're not using
this
in the lambda you don't need to capture it. Don't make the optimizer's job harder than it needs to be.@Chris-Kawa Thanks for the insight and tip regarding unnecessary capture.
-
Are we allow to call the connect method that is part of QSlider or must we call connect from a parent to perform the connection?
The member function
QObject::connect(...)
is just a convenience inline wrapper for the static one, so you can call it on any level of inheritance or directly the static one and it's all the same. The various overloads are there just for convenience, soslider->connect
,QSlider::connect
andQObject::connect
are all the same and you can call any of them to the same effect.Is self connection allowed ?
Yes, same object can be used as a sender and receiver.
slider->connect(slider, &QSlider::valueChanged, [this](int intValue)
Just a note here. Since you're not using
this
in the lambda you don't need to capture it. Don't make the optimizer's job harder than it needs to be.@Chris-Kawa said in QSlider connect and C++ lambda ?:
Just a note here. Since you're not using this in the lambda you don't need to capture it.
Just an additional note. If you are actually using
this
inside the lambda, usethis
as context object (third parameter, right before the lambda) inside theconnect()
. If it's another object, use that object instead. Once the context object is deleted it will automatically disconnect the lambda. You'll get some strange behavior if you are calling a slot on a deleted object.In your specific example a context object is not needed.