How to paint above the widget original painting?
-
I'm trying to temporarily draw a border around specific widgets at a given ocasiation, for this i'm installing an
eventFilterand painting the border in theQEvent::Paint.This does work when its a Qframe/QWidget, but not when its a
QLineEdit,QPushButton, in these, the border is not visible:
The border probably is being overridden by the widget paint event.
When i change the painter to draw a rect instead of a roundedRect:
painter.drawRect(widget->rect());
In this use case, how I could make things be drawn "above" the widget original painting like its happening on the QFrame?
bool MainWindow::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::Paint) { QWidget* widget = qobject_cast<QWidget*>(obj); QPainter painter(widget); //painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(QColor(Qt::red), 2)); painter.drawRoundedRect(widget->rect().adjusted(1, 1, -1, -1), 12, 12); } return QWidget::eventFilter(obj, event); } MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindowClass()) { ui->setupUi(this); QFrame* frame = new QFrame(this); frame->setGeometry(0, 30, 200, 32); frame->installEventFilter(this); frame->setStyleSheet("background-color: blue; border-radius: 12px;"); frame->show(); QLineEdit* lineEdit = new QLineEdit(this); lineEdit->setGeometry(0, 90, 200, 32); lineEdit->installEventFilter(this); lineEdit->setStyleSheet("background-color: blue; border-radius: 12px;"); lineEdit->show(); } -
@Christian-Ehrlicher how to override it from the filter?
@Daniella Event filter is for filtering events i.e. it happens before the event and can pass the event on or stop it. That being said you can't paint over what's done in paintEvent when you're in the filter, because filtering happens before paintEvent.
As Christian said you should paint in paintEvent of the widget. Call the base implementation and then add your painting on top of it. If you don't want to modify the widget class your other option is to make an "overlay" widget on top of that one and paint in it, but in any case painting goes in paintEvent. -
I'm trying to temporarily draw a border around specific widgets at a given ocasiation, for this i'm installing an
eventFilterand painting the border in theQEvent::Paint.This does work when its a Qframe/QWidget, but not when its a
QLineEdit,QPushButton, in these, the border is not visible:
The border probably is being overridden by the widget paint event.
When i change the painter to draw a rect instead of a roundedRect:
painter.drawRect(widget->rect());
In this use case, how I could make things be drawn "above" the widget original painting like its happening on the QFrame?
bool MainWindow::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::Paint) { QWidget* widget = qobject_cast<QWidget*>(obj); QPainter painter(widget); //painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(QColor(Qt::red), 2)); painter.drawRoundedRect(widget->rect().adjusted(1, 1, -1, -1), 12, 12); } return QWidget::eventFilter(obj, event); } MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindowClass()) { ui->setupUi(this); QFrame* frame = new QFrame(this); frame->setGeometry(0, 30, 200, 32); frame->installEventFilter(this); frame->setStyleSheet("background-color: blue; border-radius: 12px;"); frame->show(); QLineEdit* lineEdit = new QLineEdit(this); lineEdit->setGeometry(0, 90, 200, 32); lineEdit->installEventFilter(this); lineEdit->setStyleSheet("background-color: blue; border-radius: 12px;"); lineEdit->show(); }When you want custom painting you should override the paintEvent.
-
When you want custom painting you should override the paintEvent.
@Christian-Ehrlicher how to override it from the filter?
-
@Christian-Ehrlicher how to override it from the filter?
@Daniella said in How to paint above the widget original painting?:
how to override it from the filter?
?
You have to override the paint function. -
@Christian-Ehrlicher how to override it from the filter?
-
@Christian-Ehrlicher how to override it from the filter?
@Daniella Event filter is for filtering events i.e. it happens before the event and can pass the event on or stop it. That being said you can't paint over what's done in paintEvent when you're in the filter, because filtering happens before paintEvent.
As Christian said you should paint in paintEvent of the widget. Call the base implementation and then add your painting on top of it. If you don't want to modify the widget class your other option is to make an "overlay" widget on top of that one and paint in it, but in any case painting goes in paintEvent. -
D Daniella has marked this topic as solved on
-
@Daniella Event filter is for filtering events i.e. it happens before the event and can pass the event on or stop it. That being said you can't paint over what's done in paintEvent when you're in the filter, because filtering happens before paintEvent.
As Christian said you should paint in paintEvent of the widget. Call the base implementation and then add your painting on top of it. If you don't want to modify the widget class your other option is to make an "overlay" widget on top of that one and paint in it, but in any case painting goes in paintEvent.@Chris-Kawa said in How to paint above the widget original painting?:
That being said you can't paint over what's done in paintEvent when you're in the filter, because filtering happens before paintEvent.
...Unless eventFilter() calls the target object's event(), followed by any postprocessing, and finally returning true to subvert the normal call to QObject::event().
This breaks if there is more than one event filter expecting to exploit the same path, and is unlikely to make anyone happy.
-
@Chris-Kawa said in How to paint above the widget original painting?:
That being said you can't paint over what's done in paintEvent when you're in the filter, because filtering happens before paintEvent.
...Unless eventFilter() calls the target object's event(), followed by any postprocessing, and finally returning true to subvert the normal call to QObject::event().
This breaks if there is more than one event filter expecting to exploit the same path, and is unlikely to make anyone happy.
@jeremy_k Well yeah, technically, but why work this hard to shoot yourself in the foot when there's a perfectly valid solution in line with what the system was actually designed for.
-
@jeremy_k Well yeah, technically, but why work this hard to shoot yourself in the foot when there's a perfectly valid solution in line with what the system was actually designed for.
@Chris-Kawa said in How to paint above the widget original painting?:
@jeremy_k Well yeah, technically, but why work this hard to shoot yourself in the foot when there's a perfectly valid solution in line with what the system was actually designed for.
Sometimes the lesson is more memorably when someone else loses a foot.
:D -
@Chris-Kawa said in How to paint above the widget original painting?:
@jeremy_k Well yeah, technically, but why work this hard to shoot yourself in the foot when there's a perfectly valid solution in line with what the system was actually designed for.
Sometimes the lesson is more memorably when someone else loses a foot.
:D