在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
#include
#include
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的初始化:
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(event);
if (mouseEvent->buttons() & Qt::LeftButton)
{
emit imageLabelClicked();
return true;
}
}
}
return QLineEdit::eventFilter(obj, event);
}
注意:
完整的logedit.cpp的实现是:
#include "logedit.h"
#include
#include
#include
#include
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(event);
if (mouseEvent->buttons() & Qt::LeftButton)
{
emit imageLabelClicked();
return true;
}
}
}
return QLineEdit::eventFilter(obj, event);
}
具体效果是:
PS:
建立了logedit的类后,上下连个输入框是两个不同的实例化类,因为已经有了imageClicked的信号,
对于该信号的处理可以有不同的方式,例如上面显示的,上一个输入行是箭头由上变成下,下面的是
变成了蓝色的键盘,在实际的qq登录是会弹出相应的菜单,这里只需要对该信号的处理机制进行编写
即可实现