2014-11-19 11 views
7

Ich habe einen Dialog, der zum Beispiel QLineEdit hat und ich möchte den Benutzer benachrichtigen, wenn der Text in der QLineEdit falsch ist und warum es falsch ist. Ich würde gerne ein kleines Pop-up neben der QLineEdit zeigen, die zum Beispiel sagt "Diese Zeichenfolge hat keinen Vokal". Ich habe versucht QToolTip::showText, aber dies ist nur ein temporäres Popup, das nach einer Mausbewegung verschwindet. Ich möchte sicherlich keine Art von QMessageBox. Was wäre der richtige Weg, dies zu tun?Popup-Benachrichtigung über falsche Eingabe in Qt

Antwort

11

Ich mag diese Frage, ich habe es als eine besondere betrachtet und ich habe mir die Zeit genommen, um das Benachrichtigungs-Popup zu erstellen, ich denke, Sie wollen. Ich habe eine Testanwendung mit einer einfachen QPushButton erstellt, die das Popup anzeigt. Sie können immer show und hide es abhängig von Signalen, die Sie erhalten.

Ich hoffe, das hilft, ich habe in ihm viel Freude stellen :-D

Hier ist das Endergebnis:

enter image description here

Hier ist das Beispielprojekt:

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

Vielen Dank, das ist genau das, was ich wollte. Eine Sache ist jedoch, dass diese Lösung den Fokus stiehlt.Für die Lösung, die Fokus nicht stehlen, brauchen wir das. setWindowFlags (Qt :: FramelessWindowHint | Qt :: Tool); setAttribute (Qt :: WA_ShowWithoutActivating); setAttribute (Qt :: WA_TranslucentBackground); Könnten Sie das bitte im Beispiel ändern? – tach

+0

@tach Fertig! Vielen Dank! : D – Iuliu

+0

@luliu Danke für deinen Code. Es ist wirklich ein gutes Beispiel. Meine Frage ist, gibt es eine einfache Möglichkeit, dieses Popup-Label auf die gleiche Weise wie die Animation verschwinden zu lassen? – Horizon1710

4

Sie können eine QToolTip erstellen, die aktiv bleibt, bis die Zeit abgelaufen ist oder Sie rufen: QToolTip::hideText()

du schaffen QToolTip mit einem Aufruf an diese statische Funktion: http://qt-project.org/doc/qt-5/qtooltip.html#showText-2

in einer -1 Passing für die msecDlayTime wird die QToolTip verlassen, bis der Benutzer die Maus klickt.

Der Nachteil ist, dass nur die neueste Version von Qt dies unterstützt.

+0

Dies ist eine gute Lösung, sein Nachteil ist, dass nur eine Quick-Info auf einmal vorhanden sein kann, . – tach

Verwandte Themen