K.Robert
K.Robert

Reputation: 235

How to draw a shape right at the position of the QPushButton clicked on?

//oneLed.h
#pragma once

#include<QPushButton>

class oneLed :public QPushButton
{
    Q_OBJECT

public:
    oneLed(QWidget* parent = 0);
protected:
    void doPainting();
};

#include"oneLed.h"
#include<QPainter>
oneLed::oneLed(QWidget* parent)
    :QPushButton(parent)
{
    connect(this, &QPushButton::clicked, this, &oneLed::doPainting);
}

void oneLed::doPainting()
{
        QPainter painter(this);
        //painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(QBrush("#888"), 1));
        painter.setBrush(QBrush(QColor("#888")));
        painter.drawEllipse(0, 0, this->width(), this->height());
        //painter.drawEllipse(0, 0, 30, 30);

}

//main.cpp
#include"oneLed.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    oneLed w;
    w.resize(100, 500);
    w.show();
    return a.exec();
}

I want to achieve the following effect: When I clicked on the oneLed object, A circle appears at the position of the oneled object. When I click on the oneLed object again, the circle disappears.

But in fact when I click on the oneLed object, the circle doesn't appear.

Upvotes: 0

Views: 1870

Answers (2)

eyllanesc
eyllanesc

Reputation: 244003

The method that you implement is paintEvent, in the slot that doPainting you must change a flag and call the update() method.

Important: The update method calls paintEvent.

oneLed.h

#ifndef ONELED_H
#define ONELED_H

#include <QPushButton>

class oneLed : public QPushButton
{
    Q_OBJECT
public:
    oneLed(QWidget* parent = 0);

protected:
    void paintEvent(QPaintEvent * event);

private slots:
    void doPainting();

private:
     bool state;
};

#endif // ONELED_H

oneLed.cpp

#include "oneled.h"
#include <QPainter>

oneLed::oneLed(QWidget *parent):QPushButton(parent)
{
    state = false;
    connect(this, &QPushButton::clicked, this, &oneLed::doPainting);
}

void oneLed::paintEvent(QPaintEvent *event)
{
    QPushButton::paintEvent(event);
    if(state){
        QPainter painter(this);
        //painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(QPen(QBrush("#888"), 1));
        painter.setBrush(QBrush(QColor("#888")));
        painter.drawEllipse(0, 0, width(), height());
    }

}

void oneLed::doPainting()
{
    state = !state;
    update();
}

Upvotes: 2

Massimo Callegari
Massimo Callegari

Reputation: 2107

I guess you got it wrong. What happens in your code is:

  • the button is clicked and your doPainting slot is called
  • you do your custom painting
  • the actual button paint event is triggered by Qt main event loop and overwrites your painting

You need to override the paintEvent method.

In your custom slot, raise a boolean flag that indicates the button has been pressed.

void oneLed::slotClicked()
{
    m_clicked = !m_clicked;
}

Then do something like this:

void oneLed::paintEvent(QPaintEvent *event)
{
    // first render the Qt button
    QPushButton::paintEvent(event);
    // afterward, do custom painting over it
    if (m_clicked)
    {
        QPainter painter(this);
        painter.setPen(QPen(QBrush("#888"), 1));
        painter.setBrush(QBrush(QColor("#888")));
        painter.drawEllipse(0, 0, this->width(), this->height());
    }
}

Upvotes: 2

Related Questions