[Qt-interest] QDate representation in QCombobox

Anders Bakken anders.bakken at myriadgroup.com
Fri Jul 23 00:39:10 CEST 2010


On Thu, Jul 22, 2010 at 03:42:47AM +0100, Petric Frank wrote:
> Hello,
>
> i have a model (QSqlTableModel) set to an instance of QCombox (->setModel).
> This comboc box is configured to be not editable.
> >From the model i select a column which represents a date and passed it to the
> combo box instance. I've verified that the data returned from the model is of
> type QVariant::Date.
>
> For the QComboBox instance i set the delegate to my own one to so that i get
> my own representation of the date value.
> This works well for the items in the drop-down list, but not for the one in
> the selected field.
>
> Where i have to set the delegate to get my representation of the date in the
> selected field ?

It turns out it's a terrible ordeal.

The text on the combo box when not opened is not painted by a delegate.
It kinda should be but that's too late to change now.

This usually leaves you with the option of changing the style or
reimplementing paintEvent.

The former is usually cleaner but in this case I think I would go for
the latter for this reason.

The style option passed to the style for painting the text converts the
date into a string using QVariant::toString() which uses the rather
illusive under-the-hood methods of QVariant for its conversion.

It does turn out that you can find the QDate using the following
approach:

QVariant foo = styleOption->currentText;
QDate date = foo.toDate();

but that's kinda nasty.

Moreover the style is not passed a pointer to the combobox itself so
you'd have to hack horribly to get a hold of the actual model to find
the real value.

That being said the paintEvent of QComboBox is rather nice and short and
the parts of it that you don't want to change can easily be changed so I
would recommend this method.

I did throw together an example taking the first approach but I would
rather do something like this:

class MyCombo : ...
{
    void paintEvent(...)
    {
        QStylePainter painter(this);
        painter.setPen(palette().color(QPalette::Text));

        // draw the combobox frame, focusrect and selected etc.
        QStyleOptionComboBox opt;
        initStyleOption(&opt);
        /* All other lines are copied from qcombobox.cpp

        inside here you could do something along the lines of:

        opt.currentText = myConversionOfDateToString(currentIndex().data().toDate());

        */

        painter.drawComplexControl(QStyle::CC_ComboBox, opt);

        // draw the icon and text
        painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
    }
};

I've attached the example I did write.

regards

--
Anders Bakken

This message, including attachments, is intended solely for the addressee indicated in this message and is strictly confidential or otherwise privileged. If you are not the intended recipient (or responsible for delivery of the message to such person) : - (1) please immediately (i) notify the sender by reply email and (ii) delete this message and attachments, - (2) any use, copy or dissemination of this transmission is strictly prohibited. If you or your employer does not consent to Internet email messages of this kind, please advise Myriad Group AG by reply e-mail immediately. Opinions, conclusions and other information expressed in this message are not given or endorsed by Myriad Group AG unless otherwise indicated by an authorized representative independent of this message.
-------------- next part --------------
#include <QtGui>

class Style : public QPlastiqueStyle
{
    Q_OBJECT
public:
    void drawControl(ControlElement element, const QStyleOption *option,
                     QPainter *painter, const QWidget *widget) const
    {
        if (element == CE_ComboBoxLabel) {
            QDate date = QVariant(qstyleoption_cast<const QStyleOptionComboBox*>(option)->currentText).toDate();
            painter->drawText(option->rect, Qt::AlignCenter, QString::number(date.day()));
        } else {
            QPlastiqueStyle::drawControl(element, option, painter, widget);
        }
    }
};

class ItemDelegate : public QStyledItemDelegate
{
public:
    void paint(QPainter *painter,
               const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        painter->drawText(option.rect, Qt::AlignCenter, QString::number(index.data().toDate().day()));
    }
};
#include "main.moc"


int main(int argc, char **argv)
{
    QApplication a(argc, argv);
    QStandardItemModel model;
    for (int i=0; i<10; ++i) {
        QStandardItem *item = new QStandardItem;
        item->setData(QDate::currentDate().addDays(i), Qt::DisplayRole);
        model.setItem(i, 0, item);
    }
    ItemDelegate id;
    QComboBox box;
    box.setStyle(new Style);
    box.setItemDelegate(&id);
    box.setModel(&model);
    box.show();
    return a.exec();
}



More information about the Qt-interest-old mailing list