关于Qt错误输入的弹出通知

时间:2014-11-19 19:29:42

标签: qt validation popup

我有一个对话框,例如QLineEdit,我希望在QLineEdit中的文字错误以及错误原因时通知用户。我想在QLineEdit旁边显示一个小弹出窗口,例如“此字符串没有元音”。我试过QToolTip::showText,但这只是临时弹出窗口,在鼠标移动后会消失。我当然不想要任何QMessageBox。这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:13)

我喜欢这个问题,我认为它是一个特殊的问题,我花时间构建了我认为你想要的通知弹出窗口。我用一个简单的QPushButton构建了一个测试应用程序,它显示了弹出窗口。根据您收到的信号,您可以随时showhide

我希望这会有所帮助,我在其中放了很多快乐:-D

以下是最终结果:

enter image description here

以下是示例项目:

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();
}

答案 1 :(得分:4)

您可以创建一个保持有效的QToolTip,直到时间到期或致电:QToolTip::hideText()

您通过调用此静态函数创建此QToolTiphttp://qt-project.org/doc/qt-5/qtooltip.html#showText-2

msecDlayTime传入-1会使QToolTip保持不变直到用户点击鼠标。

缺点是只有最新版本的Qt支持此功能。