How to paint on a label created in QDialog class?
-
I have a lineEdit inside a label(the pink label in the picture). When the user types something inside that lineEdit, an arc must be drawn from 0 to 120 degree on the label. After searching about painting on label , I found out that first I have to define a new class which inherits QLabel class and reimplement paintEvent inside that class (This solution is from here).
Therefore I added a new class named as "mylabel" which inherits QLabel and reimplemented QPaintevent inside that class, then inside the dialog class, I tried to draw that arc by typing inside the lineEdit, but nothing is drawn and I got error: painter not active.I would appreciate if someone could help me.
Here is the code:
mylabel.h:
#ifndef MYLABEL_H #define MYLABEL_H #include <QObject> #include <QLabel> class MyLabel : public QLabel { Q_OBJECT public: MyLabel(QWidget *parent = 0); void paintEvent(QPaintEvent *); }; #endifmylabel.cpp:
#include "mylabel.h" #include <QLabel> MyLabel::MyLabel(QWidget *parent) : QLabel(parent) { /*...*/ } void MyLabel::paintEvent(QPaintEvent *) { }dialog.h:
#ifndef DIALOG_H #define DIALOG_H #include "mylabel.h" #include <QDialog> #include <QLineEdit> #include <QVariantAnimation> #include <QPainter> #include <QLabel> #include <QWidget> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); QLineEdit *lineEdit_1; QLabel *label; int progress; public slots: void setProgress(); private: Ui::Dialog *ui; protected: void paintEvent(QPaintEvent *); }; #endif // DIALOG_Hdialog.cpp:
#include "dialog.h" #include "ui_dialog.h" #include <QGraphicsDropShadowEffect> #include <QLabel> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); label = new QLabel(this); label->setGeometry(50,50,600,500); label->show(); label->setObjectName("label"); label->setStyleSheet( " QLabel#label{" " background-color: pink;" "}" ); lineEdit_1 = new QLineEdit(label); lineEdit_1->setGeometry(400,50,100,50); lineEdit_1->show(); connect(lineEdit_1, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress())); } Dialog::~Dialog() { delete ui; } void Dialog::setProgress() { progress = 120; this->update(); } void Dialog::paintEvent(QPaintEvent *e) { MyLabel mylabel; mylabel.paintEvent(e); QPainter p(label); QPen pen(QBrush("#00FF00"), 10); p.setPen(pen); p.setRenderHint(QPainter::Antialiasing); QRectF rectangle(100.0, 100.0, 100.0, 100.0); int startAngle = 0; int spanAngle = progress * 16; p.drawArc(rectangle, startAngle, spanAngle); }main.cpp:
#include "dialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); }my output:

-
You can't call a widget's paintEvent inside another's, neither can you create a QPainter of a widget inside another's paintEvent.
The point of creating a new class inherits QLabel is that you must do the drawing in its paintEvent. -
@Bonnie Thank you for replying. Could you give suggestions for my case (that I want to paint on the label which is inside QDialog window)? How can I draw on the pink label I posted?
@nanor
Hi
Move the paint code from
void Dialog::paintEvent(QPaintEvent *e)
to
void MyLabel::paintEvent(QPaintEvent *)Then add a new function to MyLabel like
MyLabel::SetProgress(int progressValue ) {
progress = progressValue; // progress is a new variable to put in MyLabel.h (in class) so PaintEvent can use it
update(); // make label paint it self
}Then in your slot setProgress you can
mylabel->SetProgress(value from edit )
and the label will redraw. -
@nanor
Hi
Move the paint code from
void Dialog::paintEvent(QPaintEvent *e)
to
void MyLabel::paintEvent(QPaintEvent *)Then add a new function to MyLabel like
MyLabel::SetProgress(int progressValue ) {
progress = progressValue; // progress is a new variable to put in MyLabel.h (in class) so PaintEvent can use it
update(); // make label paint it self
}Then in your slot setProgress you can
mylabel->SetProgress(value from edit )
and the label will redraw.@mrjj said in How to paint on a label created in QDialog class?:
mylabel->SetProgress(value from edit )
Hi
Thank you for replying.
I changed my code as you said. I got the error "label was not declared in this scope" (this error is related to the line : "QPainter p(label);" inside the paintevent in MyLabel class).
As the label exists inside the window of QDialog class, how can I fix this error?Here is the code:
mylabel.h:
#ifndef MYLABEL_H #define MYLABEL_H #include <QObject> #include <QLabel> #include "dialog.h" class MyLabel : public QLabel { Q_OBJECT public: MyLabel(QWidget *parent = 0); void paintEvent(QPaintEvent *); void SetProgress(int progressValue ); int progress; }; #endifmylabel.cpp:
#include "mylabel.h" #include <QLabel> MyLabel::MyLabel(QWidget *parent) : QLabel(parent) { } void MyLabel::SetProgress(int progressValue ) { progress = progressValue; update(); } void MyLabel::paintEvent(QPaintEvent *) { QPainter p(label); QPen pen(QBrush("#00FF00"), 10); p.setPen(pen); p.setRenderHint(QPainter::Antialiasing); QRectF rectangle(100.0, 100.0, 100.0, 100.0); int startAngle = 0; int spanAngle = progress * 16; p.drawArc(rectangle, startAngle, spanAngle); }dialog.h:
#ifndef DIALOG_H #define DIALOG_H #include "mylabel.h" #include <QDialog> #include <QLineEdit> #include <QVariantAnimation> #include <QPainter> #include <QLabel> #include <QWidget> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); QLineEdit *lineEdit_1; QLabel *label; int progress; public slots: void setProgress(); private: Ui::Dialog *ui; protected: void paintEvent(QPaintEvent *); }; #endif // DIALOG_Hdialog.cpp:
#include "dialog.h" #include "ui_dialog.h" #include "mylabel.h" #include <QGraphicsDropShadowEffect> #include <QLabel> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); label = new QLabel(this); label->setGeometry(50,50,600,500); label->show(); label->setObjectName("label"); label->setStyleSheet( " QLabel#label{" " background-color: pink;" "}" ); lineEdit_1 = new QLineEdit(label); lineEdit_1->setGeometry(400,50,100,50); lineEdit_1->show(); connect(lineEdit_1, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress())); } Dialog::~Dialog() { delete ui; } void Dialog::setProgress() { MyLabel mylabel; mylabel.SetProgress(120); this->update(); }main.cpp:
#include "dialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); } -
Hi
QPainter p(label); should be
QPainter p(this);void Dialog::setProgress() { MyLabel mylabel; mylabel.SetProgress(120); this->update(); }this wont work as MyLabel mylabel; will deleted very fast.
You have to make it a member of Dialog
so
MyLabel *mylabel; in Dialog class (in its h)then in Dialog constructor, you do once
mylabel = new MyLabel(this);then
void Dialog::setProgress() { mylabel->SetProgress(120); mylabel->update(); } -
Hi
QPainter p(label); should be
QPainter p(this);void Dialog::setProgress() { MyLabel mylabel; mylabel.SetProgress(120); this->update(); }this wont work as MyLabel mylabel; will deleted very fast.
You have to make it a member of Dialog
so
MyLabel *mylabel; in Dialog class (in its h)then in Dialog constructor, you do once
mylabel = new MyLabel(this);then
void Dialog::setProgress() { mylabel->SetProgress(120); mylabel->update(); }@mrjj I updated my code as you said. When I type in lineedit, nothing is drawn.
dialog.h:
#ifndef DIALOG_H #define DIALOG_H #include "mylabel.h" #include <QDialog> #include <QLineEdit> #include <QVariantAnimation> #include <QPainter> #include <QLabel> #include <QWidget> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); QLineEdit *lineEdit_1; QLabel *label; MyLabel *mylabel; public slots: void setProgress(); private: Ui::Dialog *ui; }; #endif // DIALOG_Hdialog.cpp:
#include "dialog.h" #include "ui_dialog.h" #include "mylabel.h" #include <QGraphicsDropShadowEffect> #include <QLabel> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); mylabel = new MyLabel(this); label = new QLabel(this); label->setGeometry(50,50,600,500); label->show(); label->setObjectName("label"); label->setStyleSheet( " QLabel#label{" " background-color: pink;" "}" ); lineEdit_1 = new QLineEdit(label); lineEdit_1->setGeometry(400,50,100,50); lineEdit_1->show(); connect(lineEdit_1, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress())); } Dialog::~Dialog() { delete ui; } void Dialog::setProgress() { mylabel->SetProgress(120); mylabel->update(); }mylabel.h:
#ifndef MYLABEL_H #define MYLABEL_H #include <QObject> #include <QLabel> #include "dialog.h" class MyLabel : public QLabel { Q_OBJECT public: MyLabel(QWidget *parent = 0); void paintEvent(QPaintEvent *); void SetProgress(int progressValue ); int progress; }; #endifmylabel.cpp:
#include "mylabel.h" #include <QLabel> MyLabel::MyLabel(QWidget *parent) : QLabel(parent) { } void MyLabel::SetProgress(int progressValue ) { progress = progressValue; update(); } void MyLabel::paintEvent(QPaintEvent *) { QPainter p(this); QPen pen(QBrush("#00FF00"), 10); p.setPen(pen); p.setRenderHint(QPainter::Antialiasing); QRectF rectangle(100.0, 100.0, 100.0, 100.0); int startAngle = 0; int spanAngle = progress * 16; p.drawArc(rectangle, startAngle, spanAngle); } -
@mrjj I updated my code as you said. When I type in lineedit, nothing is drawn.
dialog.h:
#ifndef DIALOG_H #define DIALOG_H #include "mylabel.h" #include <QDialog> #include <QLineEdit> #include <QVariantAnimation> #include <QPainter> #include <QLabel> #include <QWidget> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); QLineEdit *lineEdit_1; QLabel *label; MyLabel *mylabel; public slots: void setProgress(); private: Ui::Dialog *ui; }; #endif // DIALOG_Hdialog.cpp:
#include "dialog.h" #include "ui_dialog.h" #include "mylabel.h" #include <QGraphicsDropShadowEffect> #include <QLabel> Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); mylabel = new MyLabel(this); label = new QLabel(this); label->setGeometry(50,50,600,500); label->show(); label->setObjectName("label"); label->setStyleSheet( " QLabel#label{" " background-color: pink;" "}" ); lineEdit_1 = new QLineEdit(label); lineEdit_1->setGeometry(400,50,100,50); lineEdit_1->show(); connect(lineEdit_1, SIGNAL(textChanged(const QString &)), this, SLOT(setProgress())); } Dialog::~Dialog() { delete ui; } void Dialog::setProgress() { mylabel->SetProgress(120); mylabel->update(); }mylabel.h:
#ifndef MYLABEL_H #define MYLABEL_H #include <QObject> #include <QLabel> #include "dialog.h" class MyLabel : public QLabel { Q_OBJECT public: MyLabel(QWidget *parent = 0); void paintEvent(QPaintEvent *); void SetProgress(int progressValue ); int progress; }; #endifmylabel.cpp:
#include "mylabel.h" #include <QLabel> MyLabel::MyLabel(QWidget *parent) : QLabel(parent) { } void MyLabel::SetProgress(int progressValue ) { progress = progressValue; update(); } void MyLabel::paintEvent(QPaintEvent *) { QPainter p(this); QPen pen(QBrush("#00FF00"), 10); p.setPen(pen); p.setRenderHint(QPainter::Antialiasing); QRectF rectangle(100.0, 100.0, 100.0, 100.0); int startAngle = 0; int spanAngle = progress * 16; p.drawArc(rectangle, startAngle, spanAngle); } -
Hi
As @JonB says
you wantmylabel = new MyLabel(this); mylabel ->setGeometry(50,50,600,500); mylabel ->show(); mylabel ->setObjectName("label"); mylabel ->setStyleSheet( " QLabel#label{" " background-color: pink;" "}" );so we use our custom one and not another plain one.
-
@nanor said in How to paint on a label created in QDialog class?:
mylabel = new MyLabel(this); label = new QLabel(this);You have created a
MyLabel, and then never used it?! Instead retaining all your code which creates aQLabel?? -
Hi
As @JonB says
you wantmylabel = new MyLabel(this); mylabel ->setGeometry(50,50,600,500); mylabel ->show(); mylabel ->setObjectName("label"); mylabel ->setStyleSheet( " QLabel#label{" " background-color: pink;" "}" );so we use our custom one and not another plain one.