当前位置: 首页 > news >正文

Qt自定义列表项与QListWidget学习

Qt自定义列表项与QListWidget学习

1. 项目概述

本项目实现了一个模拟QQ群成员列表的界面,主要展示了如何使用Qt中的QListWidget控件结合自定义控件来创建复杂的列表项。项目的主要特点包括:

  • 使用QListWidget作为列表容器
  • 创建自定义的QQItem控件作为列表项
  • 使用Qt样式表(QSS)美化界面
  • 使用Qt资源系统管理图片资源

2. 项目结构

42/
├── 42.pro           # 项目文件
├── main.cpp         # 主函数入口
├── widget.h         # 主窗口头文件
├── widget.cpp       # 主窗口实现
├── widget.ui        # 主窗口界面设计
├── qqitem.h         # 自定义列表项头文件
├── qqitem.cpp       # 自定义列表项实现
├── qqitem.ui        # 自定义列表项界面设计
├── res.qrc          # 资源文件
└── icons/           # 图标资源目录├── icon0.jpg    # 头像图片├── icon1.jpg    # 头像图片├── icon2.jpg    # 头像图片├── icon3.jpg    # 头像图片├── phone.png    # 电话图标└── search.png   # 搜索图标

3. 主窗口设计

3.1 界面设计 (widget.ui)

主窗口界面使用Qt Designer设计,主要包含以下元素:

  • 一个标题标签,显示群成员数量信息
  • 一个搜索框,包含搜索图标按钮和文本输入框
  • 一个QListWidget控件,用于显示群成员列表

界面使用垂直布局(QVBoxLayout)组织这些元素,搜索框内部使用水平布局(QHBoxLayout)。

<!-- widget.ui 主要结构 -->
<layout class="QVBoxLayout" name="verticalLayout"><item><widget class="QLabel" name="label"><!-- 标题标签属性设置 --></widget></item><item><layout class="QHBoxLayout" name="horizontalLayout"><item><widget class="QPushButton" name="pushButton"><!-- 搜索按钮属性设置 --></widget></item><item><widget class="QLineEdit" name="lineEdit"><!-- 搜索输入框属性设置 --></widget></item></layout></item><item><widget class="QListWidget" name="listWidget"><!-- 列表控件属性设置 --></widget></item>
</layout>

3.2 样式设置

主窗口中使用了Qt样式表(QSS)来美化界面元素:

/* 搜索按钮样式 */
QPushButton { border-image: url(:/icons/search.png) }/* 搜索输入框样式 */
QLineEdit { background: transparent; border: none }/* 列表项样式 */
QListWidget::item { height: 65px }
QListWidget::item:selected { background-color: rgb(200, 200, 200) }
QListWidget::item:hover { background-color: rgb(220, 220, 220) }

这些样式设置了:

  • 搜索按钮使用图片作为背景
  • 搜索输入框透明无边框
  • 列表项高度固定为65px
  • 列表项选中和悬停时的背景颜色

4. 自定义列表项设计

4.1 界面设计 (qqitem.ui)

自定义列表项使用Qt Designer设计,包含以下元素:

  • 一个头像图片标签(QLabel)
  • 一个电话图标标签(QLabel),可选显示
  • 一个名称标签(QLabel)

这些元素使用水平布局(QHBoxLayout)组织,并添加了适当的间距。

<!-- qqitem.ui 主要结构 -->
<layout class="QHBoxLayout" name="horizontalLayout"><item><spacer name="horizontalSpacer"><!-- 左侧间距 --></spacer></item><item><widget class="QWidget" name="widget" native="true"><!-- 头像容器 --><widget class="QLabel" name="icon"><!-- 头像标签属性设置 --></widget><widget class="QLabel" name="phone"><!-- 电话图标标签属性设置 --></widget></widget></item><item><widget class="QLabel" name="name"><!-- 名称标签属性设置 --></widget></item><item><spacer name="horizontalSpacer_2"><!-- 右侧间距 --></spacer></item>
</layout>

4.2 样式设置

自定义列表项中也使用了Qt样式表(QSS)来美化界面元素:

/* 头像容器样式 */
QWidget { background: transparent; border-radius: 10px }/* 头像标签样式 */
QLabel { background-color: darkgray; border-radius: 10px }/* 名称标签样式 */
QLabel { color: darkgray; font-size: 20px }

这些样式设置了:

  • 头像容器透明背景,圆角边框
  • 头像标签深灰色背景,圆角边框
  • 名称标签深灰色文字,20px字体大小

5. 代码实现

5.1 自定义列表项类 (QQItem)

5.1.1 类定义 (qqitem.h)
#ifndef QQITEM_H
#define QQITEM_H#include <QWidget>namespace Ui {
class QQItem;
}class QQItem : public QWidget
{Q_OBJECTpublic:explicit QQItem(QString icon, bool flag, QString name, QWidget *parent = nullptr);~QQItem();private:Ui::QQItem *ui;
};#endif // QQITEM_H

自定义列表项类继承自QWidget,构造函数接受三个参数:

  • icon:头像图片路径
  • flag:是否显示电话图标
  • name:成员名称
5.1.2 类实现 (qqitem.cpp)
#include "qqitem.h"
#include "ui_qqitem.h"QQItem::QQItem(QString icon, bool flag, QString name, QWidget *parent) :QWidget(parent),ui(new Ui::QQItem)
{ui->setupUi(this);QImage image(icon);ui->icon->setPixmap(QPixmap::fromImage(image.scaled(ui->icon->width(), ui->icon->height())));QImage image2(":/icons/phone.png");ui->phone->setPixmap(QPixmap::fromImage(image2.scaled(ui->phone->width(), ui->phone->height())));ui->phone->setVisible(flag);ui->name->setText(name);
}QQItem::~QQItem()
{delete ui;
}

构造函数中的主要操作:

  1. 加载头像图片,并设置到icon标签
  2. 加载电话图标,并根据flag参数决定是否显示
  3. 设置成员名称到name标签

5.2 主窗口类 (Widget)

5.2.1 类定义 (widget.h)
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;
};
#endif // WIDGET_H
5.2.2 类实现 (widget.cpp)
#include "widget.h"
#include "ui_widget.h"
#include "qqitem.h"#include <QListWidgetItem>class QQItem;Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setLayout(ui->verticalLayout);QQItem *qqItem = new QQItem(":/icons/icon1.jpg", true, "风子兰特");QQItem *qqItem1 = new QQItem(":/icons/icon0.jpg", false, "LIYOU");QQItem *qqItem2 = new QQItem(":/icons/icon2.jpg", false, "简单一点");QQItem *qqItem3 = new QQItem(":/icons/icon3.jpg", true, "Nov");QListWidgetItem *item0 = new QListWidgetItem;QListWidgetItem *item1 = new QListWidgetItem;QListWidgetItem *item2 = new QListWidgetItem;QListWidgetItem *item3 = new QListWidgetItem;ui->listWidget->addItem(item0);ui->listWidget->addItem(item1);ui->listWidget->addItem(item2);ui->listWidget->addItem(item3);ui->listWidget->setItemWidget(item0, qqItem);ui->listWidget->setItemWidget(item1, qqItem1);ui->listWidget->setItemWidget(item2, qqItem2);ui->listWidget->setItemWidget(item3, qqItem3);
}Widget::~Widget()
{delete ui;
}

主窗口构造函数中的主要操作:

  1. 创建4个自定义列表项(QQItem),设置不同的头像、电话图标显示状态和名称
  2. 创建4个列表项(QListWidgetItem)
  3. 将列表项添加到列表控件(QListWidget)
  4. 将自定义列表项设置为列表项的控件

5.3 主函数 (main.cpp)

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

主函数创建并显示主窗口,然后进入应用程序事件循环。

6. 资源管理

6.1 资源文件 (res.qrc)

<RCC><qresource prefix="/"><file>icons/icon0.jpg</file><file>icons/icon1.jpg</file><file>icons/icon2.jpg</file><file>icons/icon3.jpg</file><file>icons/phone.png</file><file>icons/search.png</file></qresource>
</RCC>

资源文件定义了项目中使用的图片资源,包括头像图片和图标。这些资源可以通过:/icons/xxx的路径在代码中访问。

7. QListWidget使用技巧

7.1 基本用法

// 创建列表项
QListWidgetItem *item = new QListWidgetItem;// 添加列表项到列表控件
listWidget->addItem(item);// 设置列表项的文本
item->setText("列表项文本");// 设置列表项的图标
item->setIcon(QIcon("图标路径"));// 设置列表项的工具提示
item->setToolTip("工具提示文本");// 设置列表项的数据
item->setData(Qt::UserRole, QVariant("自定义数据"));

7.2 自定义列表项

// 创建自定义控件
MyCustomWidget *widget = new MyCustomWidget;// 创建列表项
QListWidgetItem *item = new QListWidgetItem;// 添加列表项到列表控件
listWidget->addItem(item);// 设置列表项的大小
item->setSizeHint(widget->sizeHint());// 将自定义控件设置为列表项的控件
listWidget->setItemWidget(item, widget);

7.3 样式设置

/* 列表控件样式 */
QListWidget {background-color: white;border: 1px solid gray;outline: none; /* 去除焦点边框 */
}/* 列表项样式 */
QListWidget::item {height: 50px; /* 固定高度 */padding: 5px; /* 内边距 */border-bottom: 1px solid lightgray; /* 底部边框 */
}/* 选中列表项样式 */
QListWidget::item:selected {background-color: #e0e0e0; /* 选中背景色 */color: black; /* 选中文字颜色 */
}/* 悬停列表项样式 */
QListWidget::item:hover {background-color: #f0f0f0; /* 悬停背景色 */
}

7.4 信号与槽

// 连接列表项点击信号
connect(listWidget, &QListWidget::itemClicked, this, &MyClass::onItemClicked);// 连接列表项双击信号
connect(listWidget, &QListWidget::itemDoubleClicked, this, &MyClass::onItemDoubleClicked);// 连接当前项改变信号
connect(listWidget, &QListWidget::currentItemChanged, this, &MyClass::onCurrentItemChanged);// 槽函数实现
void MyClass::onItemClicked(QListWidgetItem *item)
{// 处理列表项点击事件int row = listWidget->row(item); // 获取行号QString text = item->text(); // 获取文本QVariant data = item->data(Qt::UserRole); // 获取自定义数据
}

8. 实现自定义列表项的步骤

  1. 创建自定义控件类

    • 继承QWidget或其他适合的控件类
    • 设计控件的界面(使用Qt Designer或代码)
    • 实现必要的功能和交互
  2. 在主窗口中使用自定义列表项

    • 创建QListWidgetItem对象
    • 创建自定义控件对象
    • 将列表项添加到QListWidget
    • 使用setItemWidget将自定义控件设置为列表项的控件
  3. 设置样式和交互

    • 使用Qt样式表(QSS)美化界面
    • 实现必要的信号与槽连接
    • 处理用户交互事件

10. 扩展功能示例

10.1 添加搜索功能

// 连接搜索输入框的文本变化信号
connect(ui->lineEdit, &QLineEdit::textChanged, this, &Widget::onSearchTextChanged);// 搜索功能实现
void Widget::onSearchTextChanged(const QString &text)
{// 遍历所有列表项for (int i = 0; i < ui->listWidget->count(); ++i){QListWidgetItem *item = ui->listWidget->item(i);QWidget *widget = ui->listWidget->itemWidget(item);QQItem *qqItem = qobject_cast<QQItem*>(widget);// 获取名称标签的文本(假设有getName方法)QString name = qqItem->getName();// 根据搜索文本显示或隐藏列表项if (text.isEmpty() || name.contains(text, Qt::CaseInsensitive)){item->setHidden(false);}else{item->setHidden(true);}}
}

10.2 添加右键菜单

// 重写上下文菜单事件
void Widget::contextMenuEvent(QContextMenuEvent *event)
{QListWidgetItem *item = ui->listWidget->itemAt(ui->listWidget->mapFromGlobal(event->globalPos()));if (item){QMenu menu(this);QAction *viewAction = menu.addAction("查看资料");QAction *chatAction = menu.addAction("发送消息");QAction *deleteAction = menu.addAction("删除好友");QAction *selectedAction = menu.exec(event->globalPos());if (selectedAction == viewAction){// 查看资料}else if (selectedAction == chatAction){// 发送消息}else if (selectedAction == deleteAction){// 删除好友ui->listWidget->takeItem(ui->listWidget->row(item));delete item;}}
}

10.3 拖放排序

// 在构造函数中启用拖放
ui->listWidget->setDragEnabled(true);
ui->listWidget->setDragDropMode(QAbstractItemView::InternalMove);
ui->listWidget->setDefaultDropAction(Qt::MoveAction);
http://www.xdnf.cn/news/1477171.html

相关文章:

  • PID控制技术深度剖析:从基础原理到高级应用(六)
  • LeetCode 刷题【66. 加一、67. 二进制求和】
  • Linux bzip2 命令使用说明
  • 大数据毕业设计选题推荐-基于大数据的宫颈癌风险因素分析与可视化系统-Spark-Hadoop-Bigdata
  • Day22_【机器学习—集成学习(2)—Bagging—随机森林算法】
  • 学习nginx location ~ .*.(js|css)?$语法规则
  • Error metrics for skewed datasets|倾斜数据集的误差指标
  • 区块链论坛社区
  • 在 ES6 中如何提取深度嵌套的对象中的指定属性
  • 【111】基于51单片机停车场车位管理系统【Proteus仿真+Keil程序+报告+原理图】
  • 从RAW到BMP:工业视觉系统图像格式的转换与优化
  • 数据结构之二叉树(1)
  • STM32-----SPI
  • JUC、JVM八股补充
  • YOLOv8 在 Intel Mac 上的 Anaconda 一键安装教程
  • JBoltAI:赋能AI数智化升级的Java级引擎——深入解析企业级AI开发框架的核心能力与行业价值
  • 待定系数法分解分式
  • 后端(JDBC)学习笔记(CLASS 1):基础篇(一)
  • VBA之Excel应用第四章第七节:单元格区域的整行或整列扩展
  • 进阶向:密码生成与管理工具
  • 【PCIe EP 设备入门学习专栏 -- 8.1.3 PCIe EP AXI Bridge Module】
  • 发布vue项目、nginx配置及问题场景(history)
  • 服务器内存和普通计算机内存在技术方面有什么区别?
  • 前端入门——案例一:登录界面设计(html+css+js)
  • 【xss基本介绍】
  • 风电塔筒有毒有害气体监测控制系统
  • Maimo-AI驱动的行业研究工作平台
  • 理想汽车智驾方案介绍 4 World model + 强化学习重建自动驾驶交互环境
  • PostgreSQL与Greenplum常见连接客户端
  • 详解 Java 中的 CopyOnWriteArrayList