简体   繁体   English

仅当鼠标悬停在QLineEdit上时,带有clearbutton的qlineedit

[英]qlineedit with clearbutton only when mouse is over the QLineEdit

I would like to have a QLineEdit that shows the clearbutton only when the mouse is over the QLineEdit (and of course the field is not empty). 我希望有一个QLineEdit仅在鼠标悬停在QLineEdit时显示clearbutton (当然,该字段不为空)。 I've captured the enter- and leave- events which set the property respectively. 我已经捕获了分别设置属性的enter和离开事件。 This works fine with the exception that it needs an initial enter and leave of the QLineEdit manually with the mouse. 除需要手动使用鼠标手动进入和退出QLineEdit之外,这可以正常工作。 How can I initiate the QLineEdit correctly, so that it works fine from the beginning? 如何正确启动QLineEdit ,以便从一开始就可以正常工作? Trying to simulate the initial mouse movements did not have the expecting results. 尝试模拟初始鼠标移动没有得到预期的结果。

cmplLineEdit.h cmplLineEdit.h

class cmplLineEdit : public QLineEdit {
    Q_OBJECT

public:
    explicit cmplLineEdit( QWidget* a_par = 0);
    ~cmplLineEdit();

private:
    void enterEvent( QEvent* a_ev);
    void leaveEvent( QEvent* a_ev);
    void enableClearButton( bool a_set, int a_del = 0);

private slots:
    void initialize( void);
};

cmplLineEdit.cpp cmplLineEdit.cpp

cmplLineEdit::cmplLineEdit( QWidget* a_par) : QLineEdit( a_par) {
    m_completeIt = a_cmpl;
    setClearButtonEnabled( false);
    setFocusPolicy( Qt::StrongFocus);
    QTimer::singleShot( 0, this, [=]( void) { initialize(); });
}

cmplLineEdit::~cmplLineEdit() {
}

bool cmplLineEdit::cursorIsInField() {
    return rect().contains(  mapFromGlobal( QCursor::pos()));
}

void cmplLineEdit::initialize( void) {
    QApplication::postEvent( this, new QEvent( ! cursorIsInField() ? QEvent::Enter : QEvent::Leave));
    QApplication::postEvent( this, new QEvent(   cursorIsInField() ? QEvent::Enter : QEvent::Leave));
}

void cmplLineEdit::enableClearButton( bool a_set, int a_del) {
    if( a_del < 0) {
      setClearButtonEnabled( a_set);
    } else
      QTimer::singleShot( a_del, this, [=]( void) { setClearButtonEnabled( a_set); });
}

void cmplLineEdit::enterEvent( QEvent* a_ev) {
    enableClearButton( true, 0);
}

void cmplLineEdit::leaveEvent( QEvent* a_ev) {
    enableClearButton( false, 0);
}

Yes, mouse tracking is on (otherwise I wouldn' get the enter- and leave-events). 是的,鼠标跟踪功能处于打开状态(否则我将无法进入事件和离开事件)。 I rewrote the code, implementing setClearButtonEnabled() by myself. 我重写了代码,自己实现了setClearButtonEnabled() Now it's working. 现在可以了。 For anybody who is interested: 对于任何有兴趣的人:

cmplEdit.h: cmplEdit.h:

#ifndef CMPLLINEEDIT_H
#define CMPLLINEEDIT_H

#include <QWidget>

#include <QLineEdit>
#include <QCompleter>
#include <QAction>

class cmplLineEdit : public QLineEdit {
   Q_OBJECT

public:
   explicit cmplLineEdit( bool a_cmpl = true, QWidget* a_par = 0);
   ~cmplLineEdit();

   static QIcon m_icoOff;
   static QIcon m_icoOn;

private:
   QAction* m_act = nullptr;
   bool m_completeIt = true;
   void enterEvent( QEvent* a_ev);
   void leaveEvent( QEvent* a_ev);
   bool cursorIsInField( void);

private slots:
   void initialize( void);
   void setClearIcon( bool a_set);
   void setClearIcon( const QString& a_txt);
};

#endif // CMPLLINEEDIT_H

cmplEdit.cpp: cmplEdit.cpp:

#include "cmplLineEdit.h"

#include <QTimer>
#include <QDebug>
#include <QStandardItemModel>
#include <QAbstractItemView>
#include <QEvent>
#include <QApplication>

QIcon cmplLineEdit::m_icoOn;
QIcon cmplLineEdit::m_icoOff;

cmplLineEdit::cmplLineEdit( bool a_cmpl, QWidget* a_par) : QLineEdit( a_par) {
   if( m_icoOn.isNull()) {
      m_icoOn = QIcon( qApp->style()->standardPixmap( QStyle::SP_LineEditClearButton));
   }

   m_completeIt = a_cmpl;
   m_act = addAction( m_icoOn, QLineEdit::ActionPosition::TrailingPosition);
   connect( this, SIGNAL( textChanged( QString)), this, SLOT( setClearIcon( QString)));
   connect( m_act, SIGNAL( triggered( bool)), this, SLOT( clear()));

   QTimer::singleShot( 0, [ this]( void) { initialize(); });
}

cmplLineEdit::~cmplLineEdit() {
}

bool cmplLineEdit::cursorIsInField() {
   return rect().contains( mapFromGlobal( QCursor::pos()));
}

void cmplLineEdit::initialize( void) {
   setClearIcon( cursorIsInField());
}

void cmplLineEdit::enterEvent( QEvent* a_ev) {
   setClearIcon( true);
}

void cmplLineEdit::leaveEvent( QEvent* a_ev) {
   setClearIcon( false);
}

void cmplLineEdit::setClearIcon( bool a_set) {
   if( m_act == nullptr)
      return;

   a_set = a_set && ! text().isEmpty();
   m_act->setIcon( a_set ? m_icoOn : QIcon());
   m_act->setVisible( a_set);
}

void cmplLineEdit::setClearIcon( const QString& a_txt) {
   setClearIcon( ! a_txt.isEmpty());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM