I have a dialog that has for example QLineEdit
and I would like to notify the user, when the text in the QLineEdit
is wrong and why it is wrong. I would like to show a small pop-up next to the QLineEdit
that says for example "this string doesn't have a vowel". I tried QToolTip::showText
, but this is only temporary popup which disappears after a mouse movement. I certainly don't want any kind of QMessageBox
. What would be the correct way to do this?
You can create a QToolTip
that remains active until the time expires or you call: QToolTip::hideText()
You create this QToolTip
with a call to this static function: http://qt-project.org/doc/qt-5/qtooltip.html#showText-2
Passing in a -1 for the msecDlayTime
will leave the QToolTip
up until the user clicks the mouse.
The downside is that only the latest version of Qt supports this.
I like this question, I've considered it a special one and I took the time to build the notification popup I think you want. I've built a test application with a simple QPushButton
which shows the popup. You can always show and hide it depending on signals you receive.
I hope this helps, I've put a lot of joy in it :-D
Here is the final result:
Here is the example project:
popup.pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Popup
TEMPLATE = app
SOURCES += main.cpp\
widget.cpp \
popupwidget.cpp
HEADERS += widget.h \
popupwidget.h
FORMS += widget.ui
popupwidget.h:
#ifndef POPUPWIDGET_H
#define POPUPWIDGET_H
#include <QWidget>
#include <QLabel>
#include <QGridLayout>
#include <QPropertyAnimation>
class PopUpWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(float popupOpacity READ getPopupOpacity WRITE setPopupOpacity)
void setPopupOpacity(float opacity);
float getPopupOpacity() const;
public:
explicit PopUpWidget(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *e);
public slots:
void setPopupText(const QString& text);
void show();
private:
QLabel label;
QGridLayout layout;
QPropertyAnimation animation;
float popupOpacity;
};
#endif // POPUPWIDGET_H
popupwidget.cpp:
#include "popupwidget.h"
#include <QPainter>
PopUpWidget::PopUpWidget(QWidget *parent) :
QWidget(parent)
{
resize(200, 50);
setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_ShowWithoutActivating);
animation.setTargetObject(this);
animation.setPropertyName("popupOpacity");
animation.setDuration(150);
label.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
layout.addWidget(&label, 0, 0);
setLayout(&layout);
}
void PopUpWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e)
// Draw the popup here
// You can always pick an image and use drawPixmap to
// draw it in order to make things simpler
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// Prepare the popup dimensions
QRect roundedRectDimensions;
roundedRectDimensions.setX(rect().x() + 5);
roundedRectDimensions.setY(rect().y() + 5);
roundedRectDimensions.setWidth(rect().width() - 10);
roundedRectDimensions.setHeight(rect().height() - 10);
painter.setBrush(QBrush(Qt::lightGray));
QPen pen;
pen.setColor(Qt::gray);
pen.setWidth(3);
painter.setPen(pen);
// Draw the popup body
painter.drawRoundedRect(roundedRectDimensions, 15, 15);
painter.setPen(Qt::NoPen);
painter.setBrush(QBrush(Qt::gray));
// Draw the popup pointer
const QPointF points[3] = {
QPoint(roundedRectDimensions.x(), roundedRectDimensions.height() / 2 - 5 + 3),
QPoint(roundedRectDimensions.x(), roundedRectDimensions.height() / 2 + 5 + 3),
QPoint(roundedRectDimensions.x() - 5, roundedRectDimensions.height() / 2 + 3)
};
painter.drawPolygon(points, 3);
}
void PopUpWidget::setPopupText(const QString &text)
{
label.setText(text);
}
void PopUpWidget::show()
{
setWindowOpacity(0.0);
animation.setStartValue(0.0);
animation.setEndValue(1.0);
QWidget::show();
animation.start();
}
void PopUpWidget::setPopupOpacity(float opacity)
{
popupOpacity = opacity;
setWindowOpacity(opacity);
}
float PopUpWidget::getPopupOpacity() const
{
return popupOpacity;
}
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "popupwidget.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void onPopUpButtonClicked();
private:
Ui::Widget *ui;
PopUpWidget *popUp;
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
popUp = new PopUpWidget(this);
connect(ui->popUpButton, SIGNAL(clicked()),
SLOT(onPopUpButtonClicked()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::onPopUpButtonClicked()
{
popUp->setPopupText("Example popup notification...");
const QPoint globalPos = ui->popUpButton->mapFromGlobal(QPoint(0, 0));
const int posX = -globalPos.x();
const int posY = -globalPos.y();
popUp->setGeometry(posX + ui->popUpButton->width(),
posY - ui->popUpButton->height() / 2,
popUp->width(),
popUp->height());
popUp->show();
}
widget.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>223</width>
<height>128</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="popUpButton">
<property name="text">
<string>Pop notification!</string>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
main.cpp:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With