Question

I'm trying to make the cells of a QTableView look like 3D clickable buttons. So that when you click on a cell, the button looks pushed. Everyone seems to think I merely want to change the colour, I need to show images of a normal button, and a pushed button, that look 3-dimensional.

I have done this already with calling QTableView::setItemDelegate(), with an appropriate ItemDelegate that will change the background of the cell when it's clicked. However I'm stuck at this point because I want some cells to be different coloured buttons based on the data they contain. So a cell with a low number would be a red button, that's also red when it's clicked, and the other cells would be different colours.

I can set the colour of the button with the TableModel, but once the button is clicked, there is no way for the ItemDelegate to know that it's supposed to be a different colour than the rest. How can you link the two so the ItemDelegate knows what colour it's supposed to be?

Also, is there simply a better way to make cells look like buttons?

Was it helpful?

Solution

You can call QModelIndex::model() from within the ItemDelegate's paint() method, since it has a QModelIndex parameter. This gives you the TableModel for the data, which you can programatically decide what colour the cell's button will be.

However, this is still not as elegant as I'd hope. Does anyone know a better way to change the appearance of table cells when in both the up and down button push states?

OTHER TIPS

Why don't you asked the index for the background color.

Something like this ...

QStyleOptionToolButton buttonOption;
const QStyleOptionViewItemV4& optionV4 = dynamic_cast<QStyleOptionViewItemV4&>(option);
//...
buttonOption.palette.setBrush( QPalette::Button, index.data( Qt::BackgroundColorRole ) ); 
//...

I have feeling that its a bug in Qt and its must have been ...

// model code  
if(role==Qt::BackgroundColorRole )
    return qvariant_cast<QBrush>( QBrush(Qt::red) );

// delegate code 
buttonOption.palette.setBrush(QPalette::Button, optionV4.backgroundBrush );

Because the optionV4.backgroundBrush is correct in the sizeHint method but is invalid in the paint method . I see now reason why the sizeHint should have the background brush and the paint method not. I'll report it to Nokia.

EDIT:

Looks like I was right and its a bug in < Qt4.5.
QStyleOptionViewItemV4 doesn't copy the icon and backgroundBrush

Can you not get the ID/row count of the table cell's row and then check it against the colour table that you may be having, and set the colour accordingly? I am not sure if I understood your question well or not.

Assign a data role for the background color, and in your item delegate, ask the model index what it's background color is (using data( bg_color_role ) or something similar). Then, in your model, you need to make sure the data function returns a color for the bg_color_role that is appropriate for the data being modeled.

The way to do that is to use the data method of the QModelIndex object you get on the paint method, and ask for a specific role (if you define a custom model, you can add your own roles, and give the information you need to the delegate in those roles.)

TimW, I think you have to fill the QStyleOptionViewItemV4 info by calling initStyleOption before.

I'm not sure where the requirement for a background image comes from. If you want the cells to look like QPushButtons, you should probably inherit from QItemDelegate and implement paint() to use QStyle to draw you a QPushButton, something like this:

QStyleOptionButton opt;
// fill 'opt' from the information from the model, and the style option that's passed in
style()->drawControl( QStyle::CE_PushButton, &opt, painter );

Have you tried using custom style sheets?

You could just apply the same stylesheet to every cell, and then change the background image / style to draw the 3D button images depending on whether or not it's selected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top