views:

42

answers:

2

i'm trying to make QSortFilterProxyModel sort items by duration.

preconditions:

  1. hours and minutes must not have leading zeros
  2. if duration is less than an hour, then hours must not be displayed, but only minutes and seconds
  3. if duration is less than a minute, then 0 minutes and the corresponding number of seconds must be displayed [0:42]

tried to store durations in the source model as H:mm:ss (http://doc.trolltech.com/4.6/qtime.html#toString) if they are one hour or longer, and as m:ss - if less than an hour, but since sorting of QStrings is alphabetical, then, for instance, 5:20 is "more" than 12:09 as its first digit is greater.

is there an elegant way to do the sorting?

+3  A: 
  • When call "setData" to set an item's data, set q QTime object directly
  • Subclass QItemDelegate and handle display by simply draw a text, override sizeHint if necessary
  • Call QAbstractItemView::setItemDelegateForColumn to set your delegate for the duration column.

By this approach, you can display your QTime data with your approach, and sort correctly.

Mason Chang
+1  A: 

my implementation of the accepted answer [DurationDelegate is a subclass of QStyledItemDelegate]:

void DurationDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
    Q_ASSERT(index.isValid());
    QStyleOptionViewItemV4 v4option = option;
    initStyleOption(&v4option, index);
    const QWidget *widget;
    const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(&option);
    v4 ? widget = v4->widget : widget = 0;
    QStyle *style = widget ? widget->style() : QApplication::style();
    if (index.model()->data(index, Qt::DisplayRole).type() == QVariant::Time) {
        QTime length = index.model()->data(index, Qt::DisplayRole).toTime();
        QString format;
        length >= QTime(1, 0) ? format = QString("H:mm:ss") : format = QString("m:ss");
        v4option.text = length.toString(format);
    }
    style->drawControl(QStyle::CE_ItemViewItem, &v4option, painter, widget);
}
theorist