Qt(二)

编程入门 行业动态 更新时间:2024-10-25 06:21:55

<a href=https://www.elefans.com/category/jswz/34/1769097.html style=Qt(二)"/>

Qt(二)

在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

注意:

  • 如果要使用Qt的信号槽机制,对象必须要有Q_OBJECT这样一个机制的声明。然后其包含的头文件是#include<QObject>,在Assitant中,原文的表达是:The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.
  • 对于继承来自QLineEdit的LogEdit,尽量保持着原函数的构造函数,对于QLineEdit的构造函数包含三个:
QLineEdit(QWidget * parent = 0)
QLineEdit(const QString & contents, QWidget * parent = 0)
~QLineEdit()

  • 添加了QLabel的事件处理,即imageLabelClicked()
  • 在这里,由于LogEdit右边需要一个菜单项,因此需要一个Label标记点击的位置,所以在LogEdit中添加了mImageLabel的成员变量
接着是是对头文件的实现,在logedit.cpp文件中实现:

首先是构造函数和析构函数的实现,

对于继承来自于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);}

 
 
对于读入的对于QLabel的图片的ICON,需要对QLabel的位置进行一定的限制,即在输入行的右下方。其次是对QLabel大小的限定。实现如下: 

首先是大小和位置的确定:

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);}
}
注意:

  • 起初是想通过读取在QtDesigner中的设计好的界面的宽度和高度,从而确定出QLabel的位置,正如注释调的语句一样,但是读取到的宽度和实际在Designer的大小不一致,万般无赖下来了一个具体的数值,宽度是178,高度是28.
  • setTextMargins是需要联想BoxModel,即在输入行的右边的Margin不为0,即输入的数据不会占据满所有的输入行空间,右边因为有QLabel存在。
接着是对鼠标按下的slot的实现:

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);
}

注意:

  • resizeEvent的实现原因是因为:This event handler can be reimplemented in a subclass to receive widget resize events which are passed in the event parameter. When resizeEvent() is called, the widget already has its new geometry.

完整的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登录是会弹出相应的菜单,这里只需要对该信号的处理机制进行编写

即可实现


更多推荐

Qt(二)

本文发布于:2024-03-08 07:28:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1720205.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Qt

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!