[Qt-interest] Derived custom widgets
Andre Somers
andre at familiesomers.nl
Mon Aug 30 07:44:27 CEST 2010
Op 29-8-2010 22:04, Neville Dastur schreef:
> I am trying to implement my own date edit control. This is to implement
> correct handling to null dates. I know the issue of null dates has been
> discussed lots and for a library with such tight database integration, I
> don't know why this isn't handled elegantly.
>
> Any how, my idea was to subclass QDateEdit to create a custom widget. I
> want an extra button to the side of the combo control to clear the date
> and be able to set the lineedit of the combo or spinbox to something
> like "No Date"
>
> The bit I am stuck on is the painting. It seems to me there are a number
> of options.
>
> 1) Derive from QWidget instead, and create a composite widget of
> QDateEdit and QToolButton. But then I have to re-implement all the
> QDateEdit members and I don't retain designer integration.
>
> 2) Do above, but write as a designer plugin, to get over last problem.
>
> 3) Derive from QDateEdit. Add some width to my sizeHint and call the
> base class to draw the date control and then paint on the extra button.
>
> From an object orientated POW it seems 3 should be the way forward.
>
> I wrote this to test:
>
> /*virtual (note without virtual makes no difference)*/
> void wdgDateEdit::paintEvent(QPaintEvent *event) {
> QDateEdit::paintEvent(event);
> QPainter p(this);
> p.drawEllipse( event->rect() );
> }
>
> /*virtual (note without virtual makes no difference)*/
> QSize wdgDateEdit::sizeHint() const {
> QSize sz = QDateEdit::sizeHint();
> sz.setWidth( sz.width() + 20 );
> DEBUG<< "DateEdit size hint "<< QDateEdit::sizeHint()<< " We
> return size "<< sz;
> return sz;
> }
>
> I expected the QDateEdit to get it's size hint from the base class size
> hint, but it doesn't. As the ellipse fills the entire
> wdgDateEdit::sizeHint() rectangle.
Well, I think judging from the snippets above, that is logical.
First of all, the virtual keyword does not matter, because every method
that has been declared virtual in a base class will also be virtual in a
derived class, no matter if you use the virtual keyword or not. I just
think it is good style to use the keyword so the API is more self-evident.
> So I thought I could modify the rect that QDateEdit::paintEvent(event);
> is acting on. But can't find a method to do so.
Actually, that is exactly what you can do, and exactly why your current
example does not work. The only thing you currently do, is to tell your
layout that you *request* a little bit more width than a standard
QDateEdit would do. Nothing more. Then, when painting, you generously
give all that extra space (if you got it at all) to the original
QDateEdit to draw on, which it happily does. Ergo: no space left for
your button.
Using the normal methods, there is not much you can do about this
either. Note that the rect and the region in the paint event are for
clipping, but do not define the area for the whole widget. That is
defined by the widget's own size, which is because you subclassed, the
same as the wdgDateEdit's size. So, normally, you would solve that using
method 1.
However, there is a way out since the introduction of Qt style sheets,
at least as long as you are using a default style. Using a style sheet,
you can use the padding (inside the border) or the margin (outside the
border) properties to create some empty space at the right of your
widget. By creating a button child widget of the QDateEdit, and
reimplementing resizeEvent() to position and size that button to the
correct place manually, you can add an extra button to the existing
QDateEdit class and keep the QDateEdit API and designer integration
(using either widget promotion from QDateEdit or a designer plugin).
An example for the approach above is to make a line edit with a clear
button inside the text area:
http://www.google.nl/search?q=qt+line+edit+clear+button
> I know some people may say get on and implement 1 or 2 above. But it is
> not as elegant. No OO and therefore not as easy to maintain. I also
> think that what I am trying to achieve should be possible with Qt.
>
> Any pointers would be appreciated.
0x2361AB62
0xAE190048
0xC4193984
I give no guarantees to what those pointers point to, or if they are
properly aligned ;-)
André
More information about the Qt-interest-old
mailing list