QComBoBox代理实现登录功能

简述

许多人在使用Qt的时候,特别是在准备做一个像登录框一样的界面的时候。在账号栏我们多见到像下图一样的情况。
本文就重点关于账号栏是实现进行讨论。大家一般第一印象就感觉应该用QComBoBox实现。但仅仅只使用QComBoBox是无法达到下图的效果的。

实现

在考虑如何实现的时候,我们要自定义一个组件来代替下拉框中的QComBoBox原生组件
下面看一下我们的例子,在这个例子我们会实现一个QLabel和一个QPushButton的横向布局并重新实现一些事件。

#ifndef LOGINWINDOWACCOUNTITEM_H
#define LOGINWINDOWACCOUNTITEM_H
//这是一个用于自定义QComboBox的代理控件
//主要会包含一个QLabel和一个QPushButton
#include <QWidget>
#include <QMouseEvent>
class QLabel;
class QPushButton;
class LoginWindowAccountItem : public QWidget
{
    Q_OBJECT

public:
    LoginWindowAccountItem(QWidget *parent=0);
    ~LoginWindowAccountItem();
    //set - get accountName
    QString getAccountName() const;
    void setAccountName(const QString&);
signals:
    void sgn_removeAccount(QString);//移除这个账户,QString为当前accountName的值
    void sgn_showAccount(QString);//展示我们刚才所选的这个Item
public slots:
    void slt_removeAccountItem();//删除账户槽
protected:
    //重写鼠标按下与释放,以此来实现点击item进行当前item的替换
    void mousePressEvent(QMouseEvent *);
    void mouseReleaseEvent(QMouseEvent *);
private:
    const int ContentsMargin = 5;//内边距
    bool isMousePress;
    QLabel *accountName;
    QPushButton *deleteIconButton;

};

#endif // LOGINWINDOWACCOUNTITEM_H

下面是cpp文件

#include "loginwindowaccountitem.h"
#include <qlabel.h>
#include <QPushButton>
#include <qpixmap.h>
#include <QHBoxLayout>
LoginWindowAccountItem::LoginWindowAccountItem(QWidget *parent)
    : QWidget(parent),isMousePress(false),accountName(new QLabel()),deleteIconButton(new QPushButton())
{
    connect(deleteIconButton, &QPushButton::clicked, this, &LoginWindowAccountItem::slt_removeAccountItem);
    QHBoxLayout *layout = new QHBoxLayout();
    layout->addWidget(accountName);
    layout->addStretch();
    layout->addWidget(deleteIconButton);
    layout->setContentsMargins(ContentsMargin, ContentsMargin, ContentsMargin, ContentsMargin);
    layout->setSpacing(ContentsMargin);
    this->setLayout(layout);
    return;
}
//set - get accountName
QString LoginWindowAccountItem::getAccountName() const
{
    return accountName->text();
}
void LoginWindowAccountItem::setAccountName(const QString& text)
{
    accountName->setText(text);
    return;
}
//移除这个账户,发送移除这个账户的信号,信号内容为当前这个item的accountName
void LoginWindowAccountItem::slt_removeAccountItem()
{
    QString removeAccountName = accountName->text();
    emit sgn_removeAccount(removeAccountName);
    return;
}
//重写鼠标按下与释放,以此来实现点击item进行当前item的替换
void LoginWindowAccountItem::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        isMousePress = true;
    }
    return;
}
void LoginWindowAccountItem::mouseReleaseEvent(QMouseEvent *event)
{
    if (isMousePress)
    {
        QString accountName = this->accountName->text();
        emit sgn_showAccount(accountName);
        isMousePress = false;
    }
    return;
}
LoginWindowAccountItem::~LoginWindowAccountItem()
{

}

好了,现在我们已经完成了代理控件的编写,下面我们来看一下在自定义的登录框中的账户栏的实现

#ifndef LOGINWINDOW_H
#define LOGINWINDOW_H

#include <QWidget>
#include "ui_loginwindow.h"
class QListWidget;
class QMessageBox;
class LoginWindow : public QWidget
{
    Q_OBJECT

public:
    LoginWindow(QWidget *parent = 0);
    ~LoginWindow();
public slots:
    void slt_removeLoginAccount(const QString&);
    void slt_showSelectedAccount(const QString&);
private:
    Ui::LoginWindow *ui;
    QListWidget *accountList;//用来替代QComBoBox的下拉框
};

#endif // LOGINWINDOW_H

下面是cpp文件

#include "loginwindow.h"
#include "loginwindowaccountitem.h"
#include <QListWidget>
#include <QLineEdit>
#include <qmessagebox.h>
#include <qdebug.h>
LoginWindow::LoginWindow(QWidget *parent)
    : QWidget(parent),accountList(new QListWidget()),ui(new Ui::LoginWindow)
{

    ui->setupUi(this);
    ui->accountComboBox->setEditable(true);//开启lineedit编辑
    //设置占位符文本
    ui->accountComboBox->lineEdit()->setPlaceholderText(u8"用户名/手机/邮箱");
    ui->accountComboBox->setModel(accountList->model());
    ui->accountComboBox->setView(accountList);
    //静态实现的下拉框中的账户,一般写项目的时候不会这样显示定义数量
    for (int i = 0; i < 3; ++i)
    {
        LoginWindowAccountItem* item = new LoginWindowAccountItem();
        item->setAccountName(QString(u8"thisItemIs")+QString::number(i) );
        connect(item, &LoginWindowAccountItem::sgn_removeAccount, this, &LoginWindow::slt_removeLoginAccount);
        connect(item, &LoginWindowAccountItem::sgn_showAccount, this, &LoginWindow::slt_showSelectedAccount);
        QListWidgetItem *listItem = new QListWidgetItem(accountList);
        accountList->setItemWidget(listItem, item);
    }
}
void LoginWindow::slt_removeLoginAccount(const QString& text)
{
    QMessageBox msgBox(QMessageBox::Information, tr(u8"提示"), tr(u8"确认删除这个账户!"), QMessageBox::Yes | QMessageBox::Cancel, NULL);
    if (msgBox.exec() == QMessageBox::Yes)
    {
        int listCount = accountList->count();
        QListWidgetItem* tempItem;
        LoginWindowAccountItem *tempAccountItem;
        QString removeItemAccountName;
        //找到这个item并删除
        for (int i = 0; i < listCount; ++i)
        {
            tempItem = accountList->item(i);
            tempAccountItem = static_cast<LoginWindowAccountItem *>(accountList->itemWidget(tempItem));
            removeItemAccountName=tempAccountItem->getAccountName();
            if (removeItemAccountName == text)
            {
                accountList->takeItem(i);
                ui->accountComboBox->setEditText("");
                delete tempItem;
                break;
            }
        }
    }
}
void LoginWindow::slt_showSelectedAccount(const QString& text)
{
    ui->accountComboBox->setEditText(text);
    ui->accountComboBox->hidePopup();
    return;
}
LoginWindow::~LoginWindow()
{
    delete ui;
}

在这里主函数的编码就不给出了,相信大家有这个基础的。
好,现在我们可以看一下效果图,由于没有进行任何的美化和修饰,可能视觉效果不是太好。但本文主要是总结一下这个实现的方法。美化的部分,可以后期加载QSS文件进行美化

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值