2014-11-19 20 views
7

Tôi có một hộp thoại có ví dụ QLineEdit và tôi muốn thông báo cho người dùng khi văn bản trong số QLineEdit sai và tại sao nó sai. Tôi muốn hiển thị cửa sổ bật lên nhỏ bên cạnh số QLineEdit, ví dụ: "chuỗi này không có nguyên âm". Tôi đã thử QToolTip::showText, nhưng đây chỉ là cửa sổ bật lên tạm thời biến mất sau một chuyển động của chuột. Tôi chắc chắn không muốn bất kỳ loại QMessageBox nào. Điều gì sẽ là cách chính xác để làm điều này?Thông báo bật lên về đầu vào sai trong Qt

Trả lời

11

Tôi thích câu hỏi này, tôi đã xem nó là một câu hỏi đặc biệt và tôi dành thời gian để xây dựng cửa sổ thông báo mà tôi nghĩ bạn muốn. Tôi đã xây dựng một ứng dụng thử nghiệm với một đơn giản QPushButton cho thấy cửa sổ bật lên. Bạn luôn có thể showhide tùy thuộc vào các tín hiệu bạn nhận được.

Tôi hy vọng điều này sẽ giúp, tôi đã đặt rất nhiều niềm vui trong nó :-D

Dưới đây là kết quả cuối cùng:

enter image description here

Đây là dự án ví 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 

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

Cảm ơn bạn rất nhiều, đây là chính xác những gì tôi muốn. Một điều mặc dù là, rằng giải pháp này đánh cắp tập trung.Đối với giải pháp, mà không ăn cắp tập trung, chúng ta cần điều này. setWindowFlags (Qt :: FramelessWindowHint | Qt :: Tool); setAttribute (Qt :: WA_ShowWithoutActivating); setAttribute (Qt :: WA_TranslucentBackground); Bạn có thể thay đổi nó trong ví dụ này không? – tach

+0

@tủ xong! Cảm ơn bạn! : D – Iuliu

+0

@luliu Cảm ơn mã của bạn. Nó thực sự là một ví dụ tốt. Câu hỏi của tôi là, có cách nào dễ dàng để làm cho nhãn bật lên này biến mất theo cùng một cách của hoạt ảnh? – Horizon1710

4

Bạn có thể tạo một QToolTip mà vẫn hoạt động cho đến khi hết thời gian hoặc bạn gọi: QToolTip::hideText()

Bạn tạo này QToolTip với một cuộc gọi đến chức năng tĩnh này: http://qt-project.org/doc/qt-5/qtooltip.html#showText-2

Đi qua trong một -1 cho msecDlayTime sẽ rời khỏi QToolTip cho đến khi người dùng nhấp chuột.

Nhược điểm là chỉ phiên bản Qt mới nhất hỗ trợ tính năng này.

+0

Đây là một giải pháp tốt, nhược điểm của nó là, rằng chỉ có một ToolTip thể có mặt cùng một lúc . – tach

Các vấn đề liên quan