Solved Custom drawn QSpinBox widget
-
Hello,
I'd like to extend QSpinBox/QDoubleSpinBox drawing so that some extra graphics is put to the right of the original spinbox. This extra content is outside of the default rectangle box of the spinbox (red area):
Deriving directly from QSpinBox saves me from re-defining/declaring a lot of set/get methods. All I need to do is to override the widget's size methods and the paintEvent() method.
I struggle with getting the correct size for the widget: If I define a size of 60x20 pixel for the whole widget (spinbox + extra content), only 40 pixel should be used for the spinbox.
QSize MySpinBox::sizeHint() const { QSize size = QDoubleSpinBox::sizeHint(); size.rwidth() += 20; // extra size for additional content qDebug() << "Hint:" << size; return size; } void MySpinBox::resizeEvent( QResizeEvent * event) { QSize newSize = event->size(); newSize.rwidth() -= 20; QResizeEvent event2(newSize, event->oldSize()); QDoubleSpinBox::resizeEvent(&event2); }
It seems my trivial approach is not getting me anywhere. Can anyone lead me into the right direction about where to look for composition of original QWidget with custom widgets?
Thank you for reading!
PauleBtw; When overriding paintEvent() with empty method, the edit box and its background still gets drawn. I wonder why that's the case:
void MySpinBox::paintEvent( QPaintEvent * event) { // nothing }
-
You safe yourself a lot of trouble if you just compose a new widget instead integrating it into a QSpinBox derived one.
One big problem which comes to my mind would be the mouse-click check done by QSpinBox internally. Which is performed using it's QStyle. Since you "resize" the widget in the size hint this wouldn't work anymore. You would need to adapt the QStyleOption and always adapt the rect in it to match the actual spinbox. Which is not possible to guarantee in all situations.So i suggest you to go like this:
Create a container widget (derived from QFrame for example). Now use QLayouts to compose the spinbox beside a QLabel. Or place the SpinBox in the container manually (call setGeometry on every resizeEvent) and paint the rectangle beside the spinbox in the container widget's paintEvent handler. -
Raven-worx,
thank you for the reply.
I will use a composed widget then. Unfortunately all access methods of QSpinBox are hidden from now on. Is there any chance I dont have to re-define them in the composite widget class?
Regards,
Paule -
just provide a getter which returns the pointer to the spinbox and make your calls on it directly.