Com\’è dura la professione!

11 aprile 2011

Delegate a delegate in a Qt View

Filed under: QT — lbell @ 20:59

The data presentation in a Qt Item View like a TreeView or a TableView is made by means of components that implement a QAbstractItemDelegate interface.

Write a custom delegate to gain full control on how the data are rendered forces us to face all the subtle details and intricacy of the measuring and styling of graphics items with the risk of producing a component that does not fit well with the style used in the host system. Moreover, speaking in a C++ term, we don’t know what is the base class that a particular view is using, so we can’t subclassing it to alter its behavior.

If our needs are limited, for example, to display a decoration over a read only standard item, a simple solution can be to use the existing view delegate to do the hard work, then render the decoration over the painted surface.

We can create a delegate deriving from QAbstractItemDelegate class, inquire the view that we want to manipulate about its actual delegate and store it as an internal variable of the new delegate. Our class can act as a bridge, implementing all the interface functions and the slots of a delegate and redirect incoming calls to the old delegate.

Our class will look like this (some code omitted for clarity)

class ElementItemDelegate : public QAbstractItemDelegate
{
    Q_OBJECT
    QAbstractItemDelegate *baseDelegate;
public:
    explicit ElementItemDelegate(QAbstractItemDelegate *newBaseDelegate, QObject *parent = 0);
    virtual ~ElementItemDelegate();
    virtual QWidget * createEditor () const;
    virtual bool editorEvent ( );
    virtual void paint ( ... ) const;
...
};

At the window creation we can retrieve the actual delegate from e. g. a tree widget and pass it to our delegate:

void MainWindow::setUpDelegates()
{
    QAbstractItemDelegate *oldDelegate = treeWidget->itemDelegate();
    ...
    ElementItemDelegate *newDelegate = new ElementItemDelegate( oldDelegate, this );
    ...
    treeWidget->setItemDelegateForColumn(0, newDelegate);
}

Each incoming call to our delegate is then redirected to the existing delegate.
The only method we are interested about is the paint() one. We let the old delegate do the hard work, then we paint:

void ElementItemDelegate::paint ( QPainter *painter, const QStyleOptionViewItem & option, 
   const QModelIndex & index ) const
{
    QStyleOptionViewItemV4 option4(option);
    // call the default delegate
    baseDelegate->paint(painter, option, index );
    Element * element = Element::fromModelIndex(index);
    if( NULL != element ) {
        QRect markRect = option.rect;
        if( option4.viewItemPosition == QStyleOptionViewItemV4::Beginning ) {
            markRect.setLeft(0);
        }
        markRect.setWidth(WIDTH_BAND);
        if( element->saved() ) {
            painter->fillRect(markRect, savedBrush);
        } else if ( element->edited() ) {
            painter->fillRect(markRect, editedBrush);
        } else {
            painter->fillRect(markRect, normalBrush);
        }
    }
}
Annunci

1 commento »

  1. Bạn đang tìm kênh đầu tư hiệu quả và an toàn Việc tiếp theo chính là lập dự
    toán chi phí xây dựng nhà ở để xác định nguồn vốn tài chính mà gia chủ mang đi đầu tư..… về giá cả
    công ty chúng tôi tốt nhất theo tiêu chuẩn xây dựng
    nhà ở của bộ xây dựng Công ty xây dựng Hòa Hưng Phát Bước thứ
    3 cũng là bước cuối cùng trong trình tự xây nhà là thi công và
    hoàn công. Hầu hết việc này được giao cho đơn vị nhà
    thầu hoàn tất…… Vĩnh Long những lời nói xuôi tai và chắc
    như đinh đóng cột nhưng sau đó là khiến bạn mất thời gian và
    tiền bạc do thiếu tính minh bạch và rõ ràng
    ngay từ lúc ký kết.,.… Chúng tôi khảo sát
    và báo giá họp lý cho quý gia chủ

    Commento di xây sửa nhà — 4 agosto 2017 @ 6:57 | Rispondi


RSS feed for comments on this post. TrackBack URI

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

Crea un sito o un blog gratuitamente presso WordPress.com.

%d blogger hanno fatto clic su Mi Piace per questo: