效果效果:
主要是重新实现了一下QListWidgetItem 以及 绑定Item的QWidget。
把QWidget绑定到QListWidgetItem的方法:
QListWidgetItem *item = new QListWidgetItem;
QWidget *wgt = new QWidget;
m_pListWidget->addItem(item);
m_pListWidget->setItemWidget(item, wgt);
只需要重新实现一下QWidget以及它的鼠标事件:鼠标双击、鼠标移入、鼠标移出事件即可。
选中的item的高度需要通过QListWidgetItem的setSizeHint()方法来实现(设置QWidget的高度不能用)
item->setSizeHint(QSize(item->sizeHint().width(), 32));
具体的代码如下:
PlayerList.cpp (主窗体)
#include "PlayerList.h"
#include <QListWidget>
#include "ItemEntity.h"
#include "WidgetProxy.h"
#include <QPropertyAnimation>
PlayerList::PlayerList(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
m_pListWidget = new QListWidget;
//设置ListWidget的背景色 以及 item的背景色
m_pListWidget->setStyleSheet("QListWidget { background:rgb(30,30,30); color:white;outline:none;} QListWidget::item{background-color:rgb(60,60,60);}"); //QListWidget::item:hover { background-color:blue;}QListWidget::item:selected { background-color:rgb(90,90,90);}
this->setCentralWidget(m_pListWidget);
//添加10个项
for (int i = 0; i < 10; i++)
{
QString itemTitle = QStringLiteral("标题标题%0").arg(i);
ItemEntity *item = new ItemEntity;
item->setSizeHint(QSize(item->sizeHint().width(), 32));
WidgetProxy *wgt = new WidgetProxy(itemTitle);
m_pListWidget->addItem(item);
m_pListWidget->setItemWidget(item, wgt);
connect(wgt, &WidgetProxy::mouseDoubleClicked, this, &PlayerList::itemSelected); //列表项双击时触发
}
}
/**
* @brief //列表项双击时触发
*/
void PlayerList::itemSelected()
{
WidgetProxy *wgt = (WidgetProxy *)this->sender(); //信号发送对象
if (wgt)
{
for (int i = 0; i < m_pListWidget->count(); i++)
{
ItemEntity *item = (ItemEntity *)m_pListWidget->item(i); //获取列表项
WidgetProxy *wgt2 = (WidgetProxy *)m_pListWidget->itemWidget(item); //获取列表对应的widget
//判断当前的信号发送的窗体
if (wgt2 == wgt)
{
item->setSizeHint(QSize(item->sizeHint().width(), 64)); //设置列表项的高度
wgt->setWgtSelected(true); //设置列表项对应的widget为选中状态
}
else
{
item->setSizeHint(QSize(item->sizeHint().width(), 32));
wgt2->setWgtSelected(false);
}
}
}
}
ItemEntity.h (重新实现QListWidgetItem):
#include "ItemEntity.h"
ItemEntity::ItemEntity(QWidget *parent)
: QListWidgetItem()
{
this->setSizeHint(QSize(this->sizeHint().width(), 32)); //默认高度
}
ItemEntity::~ItemEntity()
{
}
/**
* @brief 设置item的高度(选中后)
*/
void ItemEntity::setSelectItem()
{
this->setSizeHint(QSize(this->sizeHint().width(), 64));
}
WidgetProxy.h(绑定到item的自定义QWidget)
#pragma once
#include <QWidget>
class QLabel;
class QPushButton;
class WidgetProxy : public QWidget
{
Q_OBJECT
public:
WidgetProxy(const QString &title, QWidget *parent = nullptr);
~WidgetProxy();
void setWgtSelected(bool bSelected);
QString getTitleName();
protected:
void mouseDoubleClickEvent(QMouseEvent *event);
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
Q_SIGNALS:
void mouseDoubleClicked(); //双击窗体触发
private:
QLabel *m_pLabName; //
QPushButton *m_pBtnDel; //删除按钮(没实现功能)
QString m_strTitle; //内容
bool m_bSelected; //是否被选中
};
WidgetProxy.cpp
#include "WidgetProxy.h"
#include <QLabel>
#include <QDebug>
#include <QHBoxLayout>
#include <QPushButton>
WidgetProxy::WidgetProxy(const QString &title, QWidget *parent)
: QWidget(parent)
{
m_strTitle = title;
m_bSelected = false;
m_pLabName = new QLabel(title);
m_pBtnDel = new QPushButton(QStringLiteral("删除"));
m_pBtnDel->setFixedSize(QSize(60, 28));
m_pBtnDel->setVisible(false);
m_pBtnDel->setStyleSheet("QPushButton { border-radius:3px; background: white; color: blue; border:1px solid blue;}");
this->setStyleSheet("background-color:rgb(30,30,30);color:white"); //rgb(30,30,30)
QHBoxLayout *layout = new QHBoxLayout;
layout->setSpacing(0);
layout->setMargin(0);
layout->addWidget(m_pLabName);
//layout->addStretch();
layout->addWidget(m_pBtnDel);
this->setLayout(layout);
}
WidgetProxy::~WidgetProxy()
{
}
/**
* @brief 设置窗体是否选中
*/
void WidgetProxy::setWgtSelected(bool bSelected)
{
m_bSelected = bSelected; //保存状态
m_pBtnDel->setVisible(bSelected); //设置删除按钮是否显示
if (bSelected)
{
this->setStyleSheet("background-color:rgb(60,60,60);color:white"); //选中状态。
}
else
{
this->setStyleSheet("background-color:rgb(30,30,30);color:white");
}
}
/**
* @brief 获取内容
*/
QString WidgetProxy::getTitleName()
{
return m_strTitle;
}
/**
* @brief 鼠标双击
*/
void WidgetProxy::mouseDoubleClickEvent(QMouseEvent * event)
{
emit mouseDoubleClicked();
}
/**
* @brief 鼠标移动到控件上
*/
void WidgetProxy::enterEvent(QEvent * event)
{
if (m_bSelected)
return;
this->setStyleSheet("background-color:rgb(90,90,90);color:white");
}
/**
* @brief 鼠标离开到控件上
*/
void WidgetProxy::leaveEvent(QEvent * event)
{
if (m_bSelected)
return;
this->setStyleSheet("background-color:rgb(30,30,30);color:white");
}
完整程序:
链接:https://pan.baidu.com/s/1cShtR_NniCWBP4Cdutuqsg
提取码:rlwd
有兴趣的小伙伴可以留言交流