geschema
geschema

Reputation: 2494

Show push button with "pressed" state in QTableView

I have created a delegate to show push buttons in a QTableView. It looks like this (last two columns):
enter image description here

Here's the code for the delegate's paint method:

void PushButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                               const QModelIndex &index) const
{
    QStyleOptionButton buttonOption;
    buttonOption.state = QStyle::State_Enabled;
    buttonOption.text = this->text;
    buttonOption.rect = option.rect.adjusted(1, 1, -1, -1);
    QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
}

I'm using the table view's clicked signal to capture the clicks on the buttons and that works fine. How can I tweak the delegate so that the buttons look pressed when clicking on them?

Upvotes: 2

Views: 940

Answers (1)

Serhiy Kulish
Serhiy Kulish

Reputation: 1122

Looks like flag QStyle::State_Sunken makes button visually pressed. So try

buttonOption.state = QStyle::State_Enabled | QStyle::State_Sunken;

EDIT:

You can implement button clicking painted by delegate with changing data of QTableWidgetItem (if it was created before). For example, let's use Qt::CheckStateRole for passing a pressed state (or use any other role like Qt:UserRole + 1). In this case your paint method will be

void WidgetPixmapDelegate::paint(QPainter *painter,
                                 const QStyleOptionViewItem &option,
                                 const QModelIndex &index) const
{
    QStyleOptionButton buttonOption;
    bool isPressed = index.data(Qt::CheckStateRole).toBool();
    if (isPressed)
    {
        buttonOption.state = QStyle::State_Enabled | QStyle::State_Sunken;
    }
    else
    {
        buttonOption.state = QStyle::State_Enabled;
    }
    buttonOption.text = "Text";
    buttonOption.rect = option.rect.adjusted(1, 1, -1, -1);
    QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
}

So when you will set Qt::CheckStateRole data button will be painted as pressed.

For processing mouse event subclass QTableWidget and reimplement mouse events you need.

class ClickTableWidget : public QTableWidget
{
    Q_OBJECT
public:
    explicit ClickTableWidget(QWidget *parent = 0);

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

signals:

public slots:

};

void ClickTableWidget::mousePressEvent(QMouseEvent *event)
{
    QTableWidgetItem *item = itemAt(event->pos());
    if (item)
    {
        //check column item->column()
        item->setData(Qt::CheckStateRole, true);
    }
}

void ClickTableWidget::mouseReleaseEvent(QMouseEvent *event)
{
    QTableWidgetItem *item = itemAt(event->pos());
    if (item)
    {
        item->setData(Qt::CheckStateRole, false);
    }
}

Of course this is a primitive example and it does not check drag behaviour, mouse buttons and does not implement hover animation.

Upvotes: 1

Related Questions