文章目录
用户名控件QAccountBox
网上有很多QComboBox代理的教程,但是都存在这样那样的问题。这里有一份QComboBox + QListWidget + QStyledItemDelegate实现的QAccountBox
环境
Qt5.6.2 + VS2013
资源
效果![最终效果](https://i-blog.csdnimg.cn/blog_migrate/05b8046a1373ae3f2aa3f06cd754547d.gif)
代码
QAccountBox类
AccountBox.h
#ifndef ACCOUNTBOX_H
#define ACCOUNTBOX_H
#include <QComboBox> //基类
#include <QListWidget> //下拉视图
class QAccountBox : public QComboBox
{
Q_OBJECT
public:
explicit QAccountBox(QWidget *parent = nullptr);
~QAccountBox();
public:
/*
* 添加用户名
*@param: account {const QString &} 用户名
*@return: void
*/
void addAccount(const QString& account);
//槽函数
private slots:
/*
* 删除用户名时触发 从QListWidget删除
*@param: index {const QModelIndex &} 删除用户名的索引
*@return: void
*/
void slot_itemDeleted(const QModelIndex& index);
private:
// 作为下拉视图
QListWidget* x_pAccountListWidget;
};
#endif // ACCOUNTBOX_H
AccountBox.cpp
#include "AccountBox.h"
#include <QFile> //加载css文件
#include "MyListWidgetDelegate.h" //listwidget代理类
QAccountBox::QAccountBox(QWidget *parent)
: QComboBox(parent)
, x_pAccountListWidget(nullptr)
{
this->setEditable(true); //可编辑
this->setMouseTracking(true); //鼠标追踪
this->setMaxVisibleItems(4); //下拉最大可视数4
//加载样式表
QFile _file(":/css/style");
if (_file.open(QIODevice::ReadOnly))
{
QString _css = _file.readAll();
this->setStyleSheet(_css);
}
x_pAccountListWidget = new QListWidget(this); //QListWidget对象
QMyListWidgetDelegate* _pAccountListWidhetDelegate = new QMyListWidgetDelegate(this); //QListWIdget 代理对象
x_pAccountListWidget->setItemDelegate(_pAccountListWidhetDelegate); //绑定代理
//连接信号与槽
connect(_pAccountListWidhetDelegate, SIGNAL(itemDeleted(const QModelIndex&)), this, SLOT(slot_itemDeleted(const QModelIndex&)));
//QComboBox代理
this->setModel(x_pAccountListWidget->model());
this->setView(x_pAccountListWidget);
}
QAccountBox::~QAccountBox()
{
}
void QAccountBox::addAccount(const QString& account)
{
if (x_pAccountListWidget)
{
x_pAccountListWidget->addItem(account);
}
}
void QAccountBox::slot_itemDeleted(const QModelIndex& index)
{
if (!index.isValid())
{
return;
}
int nRow = index.row();
x_pAccountListWidget->takeItem(nRow);
hidePopup();
}
QMyListWidgetDelegate类
QMyListWidgetDelegate.h
#ifndef MYLISTWIDGETDELEGATE_H
#define MYLISTWIDGETDELEGATE_H
#include <QStyledItemDelegate> //基类
#include <QPoint> //坐标
class QMyListWidgetDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit QMyListWidgetDelegate(QObject *parent = nullptr);
~QMyListWidgetDelegate();
public:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);
signals:
void itemDeleted(const QModelIndex& index);
private:
QPoint x_mousePos; //鼠标位置
};
#endif // MYLISTWIDGETDELEGATE_H
QMyListWidgetDelegate.cpp
#include "MyListWidgetDelegate.h"
#include <QPixmap>
#include <QPainter>
#include <QMouseEvent>
#include <QApplication>
#include <QToolTip>;
QMyListWidgetDelegate::QMyListWidgetDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QMyListWidgetDelegate::~QMyListWidgetDelegate()
{
}
void QMyListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
initStyleOption(&viewOption, index);
if (option.state & QStyle::State_HasFocus)
{
viewOption.state = viewOption.state ^ QStyle::State_HasFocus;
}
QStyledItemDelegate::paint(painter, viewOption, index);
QPixmap pixmap = QPixmap(":/images/del");
QPixmap pixHover = QPixmap(":/images/del_hover");
QRect _rect = viewOption.rect;
QRect _openRect = QRect(_rect.right() - 25, _rect.top(), 20, _rect.height());
if (_openRect.contains(x_mousePos))
{
QApplication::style()->drawItemPixmap(painter, _openRect, Qt::AlignCenter, pixHover);
}
else
{
QApplication::style()->drawItemPixmap(painter, _openRect, Qt::AlignCenter, pixmap);
}
}
bool QMyListWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
QRect _rect = option.rect;
QRect _openRect = QRect(_rect.right() - 25, _rect.top(), 20, 20);
QMouseEvent* pEvent = static_cast<QMouseEvent*>(event);
x_mousePos = pEvent->pos();
// 还原鼠标样式
QApplication::restoreOverrideCursor();
if (event->type() == QEvent::MouseMove && _openRect.contains(pEvent->pos()))
{
// 设置鼠标样式为手型
QApplication::setOverrideCursor(Qt::PointingHandCursor);
QToolTip::showText(pEvent->globalPos(), QString::fromLocal8Bit("删除"));
}
if (event->type() == QEvent::MouseButtonPress && _openRect.contains(pEvent->pos()))
{
// 设置鼠标样式为手型
QApplication::setOverrideCursor(Qt::PointingHandCursor);
emit itemDeleted(index);
}
QToolTip::hideText();
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
css
QComboBox{
width:220px;
height: 30px;
padding-left: 24px;
background: white;
border-radius: 3px;
border: 1px solid #c8c8c8;
}
QComboBox:hover{
border: 1px solid #1583dd;
}
QComboBox::drop-down {
border: none;
}
QComboBox::down-arrow {
background:transparent no-repeat center center;
background-image: url(:/images/arrow_down);
}
QComboBox::down-arrow:on {
background-image: url(:/images/arrow_up);
}
QComboBox::down-arrow:hover {
background-image: url(:/images/arrow_hover);
}
QComboBox::drop-down:hover {
border: 1px;
}
QComboBox:editable {
background: url(:/images/user) no-repeat center left;
}
QComboBox:focus {
border: 1px solid #1583dd;
background: url(:/images/user_hover) no-repeat center left;
}
QListWidget::item{
/*border: 0px solid #33CCFF;*/
color:black;
padding-left:24px;
margin:0px;
background: url(:/images/user) no-repeat center left;
height:30px;
height
}
QListWidget::item:hover {
/*border: 0px solid #33CCFF;*/
border:none;
background: white;
padding-left:24px;
margin:0px;
background: url(:/images/user_hover) no-repeat center left;
background-color:#C6DFFD;
}
QListWidget{
outline:0px; /*QListWidget item 无虚线框*/
}