How to set border to widget, inherited from QFrame?

3.8k views Asked by At

I created widget of led light with radial gradient,(found example in internet). It was inheritated from qwidget and all type of borders that I could use in there are presented By QPaint. But I need more difficult shape for this LED, I saw this kind of borders in QFrame class, I inheritade my widget from it, but when I wanted to set type of border to my widget, nothing happened. May be some mistake in paintEvent method?

ledindicator.cpp

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

  LedIndicator::LedIndicator(QWidget *parent) :
   QFrame(parent)
 {
  setFixedSize(218, 218);
  lit = false;
  ledOnColor=Qt::green;
  ledOffColor=Qt::red;
  ledOnPattern = Qt::SolidPattern;
  ledOffPattern = Qt::SolidPattern;
  ledSize=400;
}

void LedIndicator::paintEvent(QPaintEvent *) {
   QPainter p(this);

 //QPen pen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin);
 //p.setPen(pen);

  QRadialGradient radialGradient(ledSize, ledSize, ledSize , ledSize + 7, ledSize + 7);
  radialGradient.setColorAt(0.0, Qt::white);
  radialGradient.setColorAt(0.2, Qt::green);
  radialGradient.setColorAt(1.0, Qt::green);

  if (lit){
     p.setBrush(QBrush( radialGradient)); //
  } else {
    p.setBrush(QBrush( radialGradient)); //ledOffColor,
  }

  p.drawRect(0,0,ledSize,ledSize);
  QFrame::setFrameStyle( QFrame::Box | QFrame::Raised);//setFrameStyle(QFrame::Box|QFrame::Raised);
  QFrame::setLineWidth(0);
  QFrame::setMidLineWidth(3);
  //setLineWidth(0);
  //
  //setFrameShape( QFrame::Shape);
}

void LedIndicator::switchLedIndicator() {
  lit = ! lit;
  repaint();
}
void LedIndicator::setState(bool state)
{
  lit = state;
  repaint();
}
void LedIndicator::toggle()
{
  lit = ! lit;
  repaint();
}

void LedIndicator::setOnColor(QColor onColor)
{
  ledOnColor=onColor;
  repaint();
}
void LedIndicator::setOffColor(QColor offColor)
{
  ledOffColor=offColor;
  repaint();
}
void LedIndicator::setOnPattern(Qt::BrushStyle onPattern)
{
  ledOnPattern=onPattern;
  repaint();
}
void LedIndicator::setOffPattern(Qt::BrushStyle offPattern)
{
  ledOffPattern=offPattern;
  repaint();
}
void LedIndicator::setLedSize(int size)
{
  ledSize=size;
  setFixedSize(size+10, size+10);
  repaint();
}

ledindicator.h

#ifndef LEDINDICATOR_H
#define LEDINDICATOR_H

#include <QWidget>
#include <QRadialGradient>
#include <QPen>
#include <QLabel>

class LedIndicator: public QFrame {
    Q_OBJECT
  public:
    LedIndicator(QWidget *parent = 0);
    void setState(bool state);
    void toggle();
    void setOnColor(QColor onColor);
    void setOffColor(QColor offColor);
    void setOnPattern(Qt::BrushStyle onPattern);
    void setOffPattern(Qt::BrushStyle offPattern);
    void setLedSize(int size);

  public slots:
    void switchLedIndicator();
  protected:
    void paintEvent(QPaintEvent *);
  private:
    QPen pen;
    bool lit;
    QColor ledOnColor;
    QColor ledOffColor;
    Qt::BrushStyle ledOnPattern;
    Qt::BrushStyle ledOffPattern;
    int ledSize;
};

#endif // LEDINDICATOR_H
1

There are 1 answers

3
eyllanesc On BEST ANSWER

You have to draw on top of the QFrame, the rectangle inside the edge you get through contentsRect(). The setFrameStyle(), setLineWidth(), and setLineWidth() methods do it in the constructor since you will call it only once.

ledindicator.h

#ifndef LEDINDICATOR_H
#define LEDINDICATOR_H

#include <QFrame>

class LedIndicator : public QFrame
{
    Q_OBJECT
    Q_PROPERTY(bool state READ state WRITE setState)
    Q_PROPERTY(QColor onColor READ onColor WRITE setOnColor)
    Q_PROPERTY(QColor offColor READ offColor WRITE setOffColor)
    Q_PROPERTY(Qt::BrushStyle onPattern READ onPattern WRITE setOnPattern)
    Q_PROPERTY(Qt::BrushStyle offPattern READ offPattern WRITE setOffPattern)
    Q_PROPERTY(int side READ side WRITE setSide)
public:
    LedIndicator(QWidget *parent = nullptr);
    bool state() const;
    void setState(bool state);

    QColor onColor() const;
    void setOnColor(const QColor &onColor);

    QColor offColor() const;
    void setOffColor(const QColor &offColor);

    Qt::BrushStyle onPattern() const;
    void setOnPattern(const Qt::BrushStyle &onPattern);

    Qt::BrushStyle offPattern() const;
    void setOffPattern(const Qt::BrushStyle &offPattern);
    int side() const;
    void setSide(int side);
public slots:
    void toggle();
protected:
    void paintEvent(QPaintEvent *event);
private:
    bool m_state;
    QColor m_onColor;
    QColor m_offColor;
    Qt::BrushStyle m_onPattern;
    Qt::BrushStyle m_offPattern;
    int m_side;
};

#endif // LEDINDICATOR_H

ledindicator.cpp

#include "ledindicator.h"

#include <QPainter>

LedIndicator::LedIndicator(QWidget *parent) :
    QFrame(parent),
    m_state(false),
    m_onColor(Qt::green),
    m_offColor(Qt::red),
    m_onPattern(Qt::SolidPattern),
    m_offPattern(Qt::SolidPattern)
{
    setFrameStyle( QFrame::Box | QFrame::Raised);
    setLineWidth(0);
    setMidLineWidth(3);
}

void LedIndicator::paintEvent(QPaintEvent *event) {
    QFrame::paintEvent(event);
    QPainter p(this);
    QBrush b = m_state ? QBrush(m_onColor, m_onPattern): QBrush(m_offColor, m_offPattern);
    p.fillRect(contentsRect(), b);
}

int LedIndicator::side() const
{
    return m_side;
}

void LedIndicator::setSide(int side)
{
    m_side = side;
    setFixedSize(side, side);
}

Qt::BrushStyle LedIndicator::offPattern() const
{
    return m_offPattern;
}

void LedIndicator::setOffPattern(const Qt::BrushStyle &offPattern)
{
    m_offPattern = offPattern;
}

void LedIndicator::toggle()
{
    setState(!state());
}

Qt::BrushStyle LedIndicator::onPattern() const
{
    return m_onPattern;
}

void LedIndicator::setOnPattern(const Qt::BrushStyle &onPattern)
{
    m_onPattern = onPattern;
}

QColor LedIndicator::offColor() const
{
    return m_offColor;
}

void LedIndicator::setOffColor(const QColor &offColor)
{
    m_offColor = offColor;
    update();
}

QColor LedIndicator::onColor() const
{
    return m_onColor;
}

void LedIndicator::setOnColor(const QColor &onColor)
{
    m_onColor = onColor;
    update();
}

bool LedIndicator::state() const
{
    return m_state;
}

void LedIndicator::setState(bool state)
{
    m_state = state;
    update();
}

enter image description here

enter image description here