在Qt中,对于QLineEdit而言,是没有menu-indicator的,这个时候要实现像qq登录界面的LineEdit:如下图所示,必须需要customize自己的LineEdit,采取的方法是继承QLineEdit,然后在自己的LineEdit添加自己的属性。
首先建立一个Qt Widget Application的工程文件,然后在工程文件中添加c++类:这里我的类名是LogEdit。
继承自QLineEdit,最后得到了关于LogEdit类的logedit.cpp和logedit.h的文件,接着开始对我们需要的edit的实现。
对于这样一个LineEdit,报刊了的输入行以及右边的一个符号,这里我们用QLabel进行装载实现。
因此头文件的内容是:
#ifndef LOGEDIT_H #define LOGEDIT_H #include <QObject> #include<QLabel> #include<QLineEdit> class LogEdit : public QLineEdit { Q_OBJECT public: explicit LogEdit(QWidget *parent = 0); explicit LogEdit(const QString & contents, QWidget *parent = 0); explicit LogEdit(const QString & contents, const QString & pic,QWidget *parent = 0); virtual ~LogEdit(); void setLabelPic(const QString strPic); signals: void imageLabelClicked(); protected: void init(); void changeLabelPosition(); protected: virtual void resizeEvent(QResizeEvent *event); virtual bool eventFilter(QObject *obj, QEvent *e); private: QString mImagePath; QLabel *mImageLabel; }; #endif // LOGEDIT_H
注意:
首先是构造函数和析构函数的实现,
对于继承来自于QLineEdit的属性,通过QLineEdit直接实现即可,重点是对新填进去的mImagePath和mImageLabel的初始化:
<span style="white-space:pre"> </span><pre name="code" class="cpp">LogEdit::LogEdit(QWidget *parent):QLineEdit(parent) { mImagePath=""; mImageLabel=NULL; setAttribute(Qt::WA_TranslucentBackground); } LogEdit::LogEdit(const QString &contents, QWidget *parent):QLineEdit(contents,parent) { mImagePath=""; mImageLabel=NULL; setAttribute(Qt::WA_TranslucentBackground); }
首先是大小和位置的确定:
void LogEdit::changeLabelPosition() { if(mImageLabel==NULL) return; if(mImagePath.isEmpty()) { mImageLabel->hide(); } else { int nHeight=this->height()-4; int nWidth=this->height()-4; mImageLabel->setMaximumSize(nWidth,nHeight); // mImageLabel->setGeometry(width()+nWidth-2,(height()-nHeight)/2,nWidth,nHeight); mImageLabel->setGeometry(178-14-2,(28-nHeight)/2,nWidth,nHeight); mImageLabel->setPixmap(QPixmap(mImagePath)); setTextMargins(0,0,height(),0); } }注意:
void LogEdit::resizeEvent(QResizeEvent *event) { QLineEdit::resizeEvent(event); changeLabelPosition(); } bool LogEdit::eventFilter(QObject *obj, QEvent *event) { if (mImageLabel && obj == mImageLabel ) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); if (mouseEvent->buttons() & Qt::LeftButton) { emit imageLabelClicked(); return true; } } } return QLineEdit::eventFilter(obj, event); }
注意:
完整的logedit.cpp的实现是:
#include "logedit.h" #include<QLineEdit> #include<QtCore> #include<QEvent> #include<QMouseEvent> LogEdit::LogEdit(QWidget *parent):QLineEdit(parent) { mImagePath=""; mImageLabel=NULL; setAttribute(Qt::WA_TranslucentBackground); } LogEdit::LogEdit(const QString &contents, QWidget *parent):QLineEdit(contents,parent) { mImagePath=""; mImageLabel=NULL; setAttribute(Qt::WA_TranslucentBackground); } void LogEdit::changeLabelPosition() { if(mImageLabel==NULL) return; if(mImagePath.isEmpty()) { mImageLabel->hide(); } else { int nHeight=this->height()-4; int nWidth=this->height()-4; mImageLabel->setMaximumSize(nWidth,nHeight); // mImageLabel->setGeometry(width()+nWidth-2,(height()-nHeight)/2,nWidth,nHeight); mImageLabel->setGeometry(178-14-2,(28-nHeight)/2,nWidth,nHeight); mImageLabel->setPixmap(QPixmap(mImagePath)); setTextMargins(0,0,height(),0); } } void LogEdit::init() { if(mImageLabel==NULL) { mImageLabel=new QLabel(this); //------// mImageLabel->setScaledContents(false); //这句实现具体的内容待考察 mImageLabel->installEventFilter(this); //设置箭头下标 } changeLabelPosition(); } LogEdit::LogEdit(const QString &contents, const QString &pic, QWidget *parent) :QLineEdit(contents,parent) { mImagePath=pic; mImageLabel=NULL; setAttribute(Qt::WA_TranslucentBackground); init(); } LogEdit::~LogEdit() { if (mImageLabel) delete mImageLabel; mImageLabel = NULL; } void LogEdit::setLabelPic(const QString strPic) { mImagePath=strPic; init(); } void LogEdit::resizeEvent(QResizeEvent *event) { QLineEdit::resizeEvent(event); changeLabelPosition(); } bool LogEdit::eventFilter(QObject *obj, QEvent *event) { if (mImageLabel && obj == mImageLabel ) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); if (mouseEvent->buttons() & Qt::LeftButton) { emit imageLabelClicked(); return true; } } } return QLineEdit::eventFilter(obj, event); }具体效果是:
PS:
建立了logedit的类后,上下连个输入框是两个不同的实例化类,因为已经有了imageClicked的信号,
对于该信号的处理可以有不同的方式,例如上面显示的,上一个输入行是箭头由上变成下,下面的是
变成了蓝色的键盘,在实际的qq登录是会弹出相应的菜单,这里只需要对该信号的处理机制进行编写
即可实现