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

tac*_*ach 9 validation qt popup

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

Iul*_*liu 13

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

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

这是最终结果:

在此输入图像描述

这是示例项目:

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

main.cpp中:

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Widget w;
    w.show();

    return a.exec();
}
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢,这正是我想要的.但有一件事是,这个解决方案窃取了焦点.对于解决方案而言,我们不需要这样做.setWindowFlags(Qt :: FramelessWindowHint | Qt :: Tool); 的setAttribute(Qt的:: WA_ShowWithoutActivating); 的setAttribute(Qt的:: WA_TranslucentBackground); 你可以在示例中更改它吗? (2认同)

Jon*_*Mee 5

您可以创建一个QToolTip在时间到期之前保持活动状态或调用:QToolTip::hideText()

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

传入 -1 表示msecDlayTime将保持QToolTip向上直到用户单击鼠标。

缺点是只有最新版本的 Qt 支持这一点。