zhuizhu 7 hónapja
szülő
commit
b5057e3a4a
5 módosított fájl, 346 hozzáadás és 169 törlés
  1. 2 0
      LearningSmartClient.pro
  2. 64 115
      MainPanel.cpp
  3. 122 54
      MainPanel.h
  4. 102 0
      utils/iconutils.cpp
  5. 56 0
      utils/iconutils.h

+ 2 - 0
LearningSmartClient.pro

@@ -34,6 +34,7 @@ SOURCES += \
     util/asynchelper.cpp \
     util/layoutbuilder.cpp \
     util/qformatter.cpp \
+    utils/iconutils.cpp \
     views/loginwindow.cpp \
     widgets/bubbletip.cpp \
     widgets/chatView/bubblemessagemanager.cpp \
@@ -75,6 +76,7 @@ HEADERS += \
     util/jsonmapper.h \
     util/layoutbuilder.h \
     util/qformatter.h \
+    utils/iconutils.h \
     views/loginwindow.h \
     widgets/bubbletip.h \
     widgets/chatView/bubblemessagemanager.h \

+ 64 - 115
MainPanel.cpp

@@ -1,130 +1,46 @@
 #include "MainPanel.h"
-#include <QSplitter>
-#include <QVBoxLayout>
-#include <QIcon>
-#include <QPixmap>
-#include <QPainter>
-#include <QPolygon>
-#include <QSizePolicy>
-#include <QTimer>
+#include "utils/iconutils.h"
+
+// Qt Core
+#include <QDebug>
 #include <QJsonDocument>
 #include <QJsonObject>
 #include <QJsonParseError>
-#include <QPen>
 #include <QResizeEvent>
-#include "network/websocketclient.h"
-#include <util/jsonmapper.h>
-
-#include <QDebug>
-
-#include <qtpromise/qpromise.h>
-#include <qtpromise/qpromisefuture.h>
-#include <qtpromise/qpromisehelpers.h>
-
+#include <QSizePolicy>
+#include <QTimer>
 #include <QtConcurrent>
 
-#include "widgets/bubbletip.h"
-#include "widgets/chatView/chatwindow.h"
-
+// Qt Widgets
 #include <QComboBox>
 #include <QFrame>
 #include <QHBoxLayout>
 #include <QLabel>
+#include <QSplitter>
+#include <QVBoxLayout>
+
+// Third Party
+#include <qtpromise/qpromise.h>
+#include <qtpromise/qpromisefuture.h>
+#include <qtpromise/qpromisehelpers.h>
+
+// Project Includes
 #include "AVPlayer/avplayerwidget.h"
 #include "api/roomapi.h"
 #include "appevent.h"
+#include "network/websocketclient.h"
+#include "themesettingswidget.h"
+#include "widgets/bubbletip.h"
+#include "widgets/chatView/chatwindow.h"
 #include "widgets/framelessbase.h"
 #include "widgets/functionbutton.h"
 #include "widgets/maskoverlay.h"
 #include "widgets/recorderwidget.h"
 #include "widgets/statswidget.h"
-// 新增:设置面板
-#include "themesettingswidget.h"
-
-namespace IconUtils {
-QIcon createSettingsIcon()
-{
-    QPixmap pix(24, 24);
-    pix.fill(Qt::transparent);
-    QPainter p(&pix);
-    p.setRenderHint(QPainter::Antialiasing);
-    p.setPen(QPen(QColor(60,60,60), 2));
-    p.drawEllipse(QPointF(12,12), 8, 8);
-    p.drawLine(QPointF(12,2), QPointF(12,6));
-    p.drawLine(QPointF(12,22), QPointF(12,18));
-    p.end();
-    return QIcon(pix);
-}
-
-QIcon createSearchIcon()
-{
-    QPixmap pix(24, 24);
-    pix.fill(Qt::transparent);
-    QPainter p(&pix);
-    p.setRenderHint(QPainter::Antialiasing);
-    p.setPen(QPen(QColor(60,60,60), 2));
-    p.drawEllipse(QPointF(10,10), 6, 6);
-    p.drawLine(QPointF(14,14), QPointF(22,22));
-    p.end();
-    return QIcon(pix);
-}
-
-QIcon createUserIcon()
-{
-    QPixmap pix(24, 24);
-    pix.fill(Qt::transparent);
-    QPainter p(&pix);
-    p.setRenderHint(QPainter::Antialiasing);
-    p.setPen(QPen(QColor(60,60,60), 2));
-    p.drawEllipse(QPointF(12,9), 5, 5);
-    p.drawRoundedRect(QRectF(6,14,12,8), 4, 4);
-    p.end();
-    return QIcon(pix);
-}
-
-QIcon createAudioDeviceIcon()
-{
-    QPixmap pix(24, 24);
-    pix.fill(Qt::transparent);
-    QPainter p(&pix);
-    p.setRenderHint(QPainter::Antialiasing);
-    p.setPen(QPen(QColor(60,60,60), 2));
-    p.drawRoundedRect(QRectF(5,6,14,12), 3, 3);
-    p.drawLine(QPointF(12,18), QPointF(12,22));
-    p.drawLine(QPointF(8,22), QPointF(16,22));
-    p.end();
-    return QIcon(pix);
-}
+#include "widgets/userprofilewidget.h"
+#include <util/jsonmapper.h>
 
-QIcon createStreamIcon()
-{
-    QPixmap pix(24, 24);
-    pix.fill(Qt::transparent);
-    QPainter p(&pix);
-    p.setRenderHint(QPainter::Antialiasing);
-    p.setPen(QPen(QColor(250,80,60), 2));
-    p.setBrush(QColor(250,80,60));
-    QPolygon tri; tri << QPoint(8,6) << QPoint(20,12) << QPoint(8,18);
-    p.drawPolygon(tri);
-    p.end();
-    return QIcon(pix);
-}
 
-QIcon createChatIcon()
-{
-    QPixmap pix(24, 24);
-    pix.fill(Qt::transparent);
-    QPainter p(&pix);
-    p.setRenderHint(QPainter::Antialiasing);
-    p.setPen(QPen(QColor(60,60,60), 2));
-    p.setBrush(Qt::NoBrush);
-    p.drawRoundedRect(QRectF(4,5,16,12), 3, 3);
-    QPolygon tail; tail << QPoint(12,17) << QPoint(10,21) << QPoint(15,18);
-    p.drawPolygon(tail);
-    p.end();
-    return QIcon(pix);
-}
-} // namespace IconUtils
 
 MainPanel::MainPanel(QWidget *parent)
     : TWidget(parent)
@@ -132,11 +48,35 @@ MainPanel::MainPanel(QWidget *parent)
 {
     setAttribute(Qt::WA_StyledBackground, true);
 
+    // ========== 初始化播放控制组件 ==========
+    initPlaybackControls();
+    
+    // ========== 初始化聊天相关组件 ==========
+    initChatComponents();
+    
+    // ========== 初始化布局组件 ==========
+    initLayoutComponents();
+    
+    // ========== 初始化功能按钮 ==========
+    initFunctionButtons();
+    
+    // ========== 连接信号槽 ==========
+    connectSignals();
+    
+    // ========== 初始化音频设备 ==========
+    initAudioDeviceSelectors();
+}
+
+void MainPanel::initPlaybackControls()
+{
     m_debounceTimer = new QTimer(this);
     m_debounceTimer->setInterval(500);
     m_debounceTimer->setSingleShot(true);
     connect(m_debounceTimer, &QTimer::timeout, this, &MainPanel::handleDebouncedPlay);
+}
 
+void MainPanel::initChatComponents()
+{
     webSocketClient = new WebSocketClient(this);
     
     // 启用WebSocket自动重连,提升聊天室稳定性
@@ -150,13 +90,14 @@ MainPanel::MainPanel(QWidget *parent)
     chatView->setAttribute(Qt::WA_DeleteOnClose, false);
     // 连接聊天窗口关闭请求信号
     connect(chatView, &ChatWindow::windowCloseRequested, this, &MainPanel::onChatWindowCloseRequested);
-    // statsWidget = new StatsWidget(this); // 暂时移除统计在此处的展示
+}
 
+void MainPanel::initLayoutComponents()
+{
+    // 创建右侧面板
     m_rightWidget = new QWidget;
     QVBoxLayout *vbox = new QVBoxLayout(m_rightWidget);
     vbox->setContentsMargins(0, 0, 0, 0);
-    // vbox->addWidget(userProfile, 0);
-    // vbox->addWidget(statsWidget, 0); // 暂时移除
     
     // 创建聊天窗口容器
     m_chatContainer = new QWidget(m_rightWidget);
@@ -165,6 +106,7 @@ MainPanel::MainPanel(QWidget *parent)
     chatLayout->addWidget(chatView);
     vbox->addWidget(m_chatContainer, 1);
 
+    // 创建主分割器
     splitter = new QSplitter(Qt::Horizontal, this);
     playerContainer = new QWidget(this);
     splitter->addWidget(playerContainer);
@@ -178,6 +120,10 @@ MainPanel::MainPanel(QWidget *parent)
     // 为playerContainer设置初始布局
     QVBoxLayout *playerLayout = new QVBoxLayout(playerContainer);
     playerLayout->setContentsMargins(0, 0, 0, 0);
+}
+
+void MainPanel::initFunctionButtons()
+{
     
     buttonGroup = new PopoverButtonGroup(Qt::Horizontal, playerContainer);
 
@@ -268,7 +214,7 @@ MainPanel::MainPanel(QWidget *parent)
     // buttonGroup->addButton(actionButton, nullptr);
     
     // 将buttonGroup添加到playerContainer的布局中
-    playerLayout = qobject_cast<QVBoxLayout*>(playerContainer->layout());
+    QVBoxLayout *playerLayout = qobject_cast<QVBoxLayout*>(playerContainer->layout());
     if (!playerLayout) {
         playerLayout = new QVBoxLayout(playerContainer);
         playerLayout->setContentsMargins(0, 0, 0, 0);
@@ -276,8 +222,15 @@ MainPanel::MainPanel(QWidget *parent)
     playerLayout->addStretch(1);  // 添加弹性空间,将buttonGroup推到底部
     playerLayout->addWidget(buttonGroup, 0);  // 添加buttonGroup到底部,不拉伸
     buttonGroup->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);  // 使用固定大小策略
+}
 
-    // initConnect
+void MainPanel::connectSignals()
+{
+    // 连接功能按钮信号
+    connect(m_streamButton, &QPushButton::clicked, this, &MainPanel::onStreamButtonClicked);
+    connect(m_chatButton, &QPushButton::clicked, this, &MainPanel::onChatButtonClicked);
+
+    // 连接WebSocket相关信号
     // 已移除与 UserProfileWidget 相关的在线状态更新
     // connect(webSocketClient, &WebSocketClient::statsUpdate, statsWidget, &StatsWidget::updateStats); // 暂时移除统计在主面板的更新
     connect(webSocketClient, &WebSocketClient::liveStatus, this, [this](const QString &msg) {
@@ -302,10 +255,6 @@ MainPanel::MainPanel(QWidget *parent)
         }
     });
 
-    // 连接按钮事件
-    connect(m_streamButton, &QPushButton::clicked, this, &MainPanel::onStreamButtonClicked);
-    connect(m_chatButton, &QPushButton::clicked, this, &MainPanel::onChatButtonClicked);
-
     // 初始化音频设备列表
     initAudioDeviceSelectors();
 }

+ 122 - 54
MainPanel.h

@@ -1,15 +1,20 @@
 #pragma once
+
+// Qt Core
 #include <QMutex>
 #include <QStringList>
 #include <QTimer>
 #include <QWaitCondition>
 #include <QWidget>
 #include <QRect>
+#include <QVector>
 #include "qobjectdefs.h"
 
-#include <QVector>
+// Qt Widgets
 #include <QPushButton>
 #include <QCheckBox>
+
+// Project includes
 #include "libs/Recorder/export.h"
 #include "widgets/framelessbase.h"  // Use TWidget as base
 
@@ -35,111 +40,174 @@ namespace ADS {
     class DockWidget;
 }
 
+/**
+ * @brief MainPanel 主面板类
+ * 
+ * MainPanel是应用程序的核心界面组件,负责管理和协调各个功能模块:
+ * - 播放器组件的显示和控制
+ * - 聊天窗口的嵌入式和独立显示
+ * - 录制和推流功能的控制
+ * - 音频设备的选择和管理
+ * - 用户界面的布局和模式切换
+ * 
+ * 该类支持多种显示模式:
+ * - 正常模式:分割器布局,左侧播放器,右侧聊天
+ * - 推流模式:隐藏聊天面板,专注于推流控制
+ * - 独立窗口模式:各组件可以独立弹出显示
+ * 
+ * @author 开发团队
+ * @date 2024
+ */
 class MainPanel : public TWidget
 {
     Q_OBJECT
 public:
+    // ========== 构造与析构 ==========
+    /**
+     * @brief 构造函数
+     * @param parent 父窗口指针
+     */
     explicit MainPanel(QWidget *parent = nullptr);
+    
+    /**
+     * @brief 析构函数
+     */
     ~MainPanel();
+    
+    // ========== 配置接口 ==========
+    /**
+     * @brief 设置用户角色列表
+     * @param roleList 角色列表,用于权限控制
+     */
     void setRole(const QStringList &roleList);
-
+    
+    /**
+     * @brief 设置推流房间ID
+     * @param room 房间ID字符串
+     */
     void setPushRoomId(const QString &room);
+    
+    /**
+     * @brief 设置播放器组件
+     * @param newPlayer 新的播放器组件指针
+     */
+    void setPlayerWidget(QWidget *newPlayer);
 
-    // 新增:独立窗口显示控制
 public slots:
+    // ========== 窗口显示控制 ==========
+    /**
+     * @brief 显示独立的录制窗口
+     */
     void showRecorderStandalone();
+    
+    /**
+     * @brief 显示独立的播放器窗口
+     */
     void showPlayerStandalone();
+    
+    /**
+     * @brief 显示独立的聊天窗口
+     */
     void showChatStandalone();
+    
+    /**
+     * @brief 将聊天窗口嵌入到主面板中
+     */
     void showChatEmbedded();
 
 signals:
+    // ========== 信号 ==========
+    /**
+     * @brief 用户点击退出按钮时发出的信号
+     */
     void logoutClicked();
 
-public slots:
-
 private:
-    void setPlayerWidget(QWidget *newPlayer);
-
-    void handleDebouncedPlay(); // 防抖处理函数
-
-    // 新增:推流时浮动工具栏控制
+    // ========== 播放控制 ==========
+    void handleDebouncedPlay();
+    
+    // ========== 界面布局控制 ==========
     void showFloatingToolbar();
     void hideFloatingToolbar();
-    void applyModeLayout(); // 新增:根据模式与窗口大小自适应布局
+    void applyModeLayout();
 
 protected:
     void resizeEvent(QResizeEvent* event) override;
     bool eventFilter(QObject *watched, QEvent *event) override;
 
 private:
+    // ========== 核心布局组件 ==========
     QSplitter *splitter = nullptr;
     QWidget *playerContainer = nullptr;
     QWidget *playerWidget = nullptr;
     QWidget *m_rightWidget = nullptr;          // 推流时整体隐藏的右侧面板(含聊天容器)
-    // 移除:UserProfileWidget *userProfile = nullptr;
+    
+    // ========== 聊天相关组件 ==========
     ChatWindow *chatView = nullptr;            // 统一的聊天窗口实例
-    // 新增:独立显示的窗口
+    QWidget *m_chatContainer = nullptr;        // 聊天窗口的容器(用于嵌入式显示)
+    WebSocketClient *webSocketClient = nullptr;
+    
+    // ========== 独立窗口组件 ==========
     RecorderWidget *m_recorderStandalone = nullptr;
     AVPlayerWidget *m_avPlayerStandalone = nullptr;
-    QWidget *m_chatContainer = nullptr;       // 聊天窗口的容器(用于嵌入式显示)
-
-    // 使用 TMainWindow 承载的独立窗口框架
+    
+    // ========== 窗口框架 ==========
     class TMainWindow *m_recorderFrame = nullptr;
     class TMainWindow *m_playerFrame = nullptr;
     class TMainWindow *m_chatFrame = nullptr;
-    // 新增:设置窗口的无边框框架
     class TMainWindow *m_settingsFrame = nullptr;
-    WebSocketClient *webSocketClient = nullptr;
-    StatsWidget *statsWidget = nullptr;
-    bool m_isStartingPlay = false;
-    QMutex m_playMutex;
-    QWaitCondition m_playCond;
-    QTimer *m_debounceTimer = nullptr;
-    QString m_pendingRoomId;
-
-    class PopoverButtonGroup *buttonGroup;
+    TMainWindow *m_compactFrame = nullptr;     // 用于承载"悬浮工具栏"的自定义标题窗口
+    
+    // ========== 功能按钮组件 ==========
+    class PopoverButtonGroup *buttonGroup = nullptr;
+    QPushButton *m_recordButton = nullptr;        // 开始录制按钮
+    class FunctionButton *m_streamButton = nullptr;        // 开始推流按钮
+    class FunctionButton *m_chatButton = nullptr;          // 聊天显示/隐藏/弹出/嵌入切换按钮
+    QPushButton *m_settingsButton = nullptr;      // 设置按钮
+    QCheckBox *m_drawCursorCheckBox = nullptr;    // 绘制鼠标指针选项
+    QCheckBox *m_syncRecordCheckBox = nullptr;    // 推流时同步录制选项
+    
+    // ========== 音频设备相关 ==========
     AudioDeviceSelectorIcon *m_audioDeviceSelector = nullptr;
     AudioDeviceSelectorIconDecoupled *m_audioDeviceSelectorDecoupled = nullptr;
-
-    // 音频设备选择弹层中的控件与数据缓存(改为使用基础控件 QComboBox)
     QComboBox *m_micWidget = nullptr;         // 麦克风下拉框
     QComboBox *m_speakerWidget = nullptr;     // 扬声器下拉框
     QVector<AMRECORDER_DEVICE> m_micDevices;      // 缓存麦克风设备列表
     QVector<AMRECORDER_DEVICE> m_speakerDevices;  // 缓存扬声器设备列表
-
-    // 新增:视频编码器选择控件与缓存
+    
+    // ========== 视频编码器相关 ==========
     QComboBox *m_encoderWidget = nullptr;         // 视频编码器下拉框
     QVector<AMRECORDER_ENCODERS> m_encoderList;   // 缓存编码器列表
     int m_selectedEncoderId = -1;                 // 当前选择的编码器 id
-
-    // 新增:录制控制按钮(从RecorderWidget移动过来)
-    QPushButton *m_recordButton = nullptr;        // 开始录制按钮
-    class FunctionButton *m_streamButton = nullptr;        // 开始推流按钮(独立FunctionButton)
-    class FunctionButton *m_chatButton = nullptr;          // 聊天显示/隐藏/弹出/嵌入切换按钮
-    QPushButton *m_settingsButton = nullptr;      // 设置按钮
-    QCheckBox *m_drawCursorCheckBox = nullptr;    // 绘制鼠标指针选项
-    QCheckBox *m_syncRecordCheckBox = nullptr;    // 推流时同步录制选项
-
-    // DockManager 附近
+    
+    // ========== 播放控制相关 ==========
+    bool m_isStartingPlay = false;
+    QMutex m_playMutex;
+    QWaitCondition m_playCond;
+    QTimer *m_debounceTimer = nullptr;
+    QString m_pendingRoomId;
+    
+    // ========== 状态管理 ==========
+    bool m_isStreaming = false;               // 推流状态跟踪
+    bool m_compactMode = false;               // 极简模式
+    QRect m_savedWindowGeometry;              // 窗口几何缓存
+    
+    // ========== 其他组件 ==========
+    StatsWidget *statsWidget = nullptr;
     ADS::DockManager *m_dockManager = nullptr;
     
-    // 推流状态跟踪
-    bool m_isStreaming = false;
-
-    // 极简模式与窗口几何缓存
-    bool m_compactMode = false;
-    QRect m_savedWindowGeometry;
-
-    // -    // 标记 buttonGroup 是否处于悬浮状态
-    // -    bool m_buttonGroupFloating = false;
-    // -
-    // 新增:用于承载“悬浮工具栏”的自定义标题窗口
-    TMainWindow *m_compactFrame = nullptr;
+private:
+    // ========== 初始化函数 ==========
+    void initPlaybackControls();
+    void initChatComponents();
+    void initLayoutComponents();
+    void initFunctionButtons();
+    void connectSignals();
+    void initAudioDeviceSelectors();
     
 private slots:
-    void initAudioDeviceSelectors();
     
-    // 新增:录制控制按钮的槽函数
+    // 录制控制按钮的槽函数
     void onRecordButtonClicked();
     void onStreamButtonClicked();
     void onChatButtonClicked();                 // 聊天弹出/嵌入/显示/隐藏按钮槽

+ 102 - 0
utils/iconutils.cpp

@@ -0,0 +1,102 @@
+#include "iconutils.h"
+
+#include "qmath.h"
+
+#include <math.h>
+
+namespace IconUtils {
+
+QIcon createSettingsIcon()
+{
+    QPixmap pixmap(24, 24);
+    pixmap.fill(Qt::transparent);
+    QPainter painter(&pixmap);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setPen(QPen(Qt::black, 2));
+    painter.drawEllipse(8, 8, 8, 8);
+    for (int i = 0; i < 8; ++i) {
+        painter.drawLine(12 + 6 * qCos(i * M_PI / 4), 12 + 6 * qSin(i * M_PI / 4),
+                        12 + 8 * qCos(i * M_PI / 4), 12 + 8 * qSin(i * M_PI / 4));
+    }
+    return QIcon(pixmap);
+}
+
+QIcon createSearchIcon()
+{
+    QPixmap pixmap(24, 24);
+    pixmap.fill(Qt::transparent);
+    QPainter painter(&pixmap);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setPen(QPen(Qt::black, 2));
+    painter.drawEllipse(6, 6, 10, 10);
+    painter.drawLine(14, 14, 18, 18);
+    return QIcon(pixmap);
+}
+
+QIcon createUserIcon()
+{
+    QPixmap pixmap(24, 24);
+    pixmap.fill(Qt::transparent);
+    QPainter painter(&pixmap);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setPen(QPen(Qt::black, 2));
+    painter.drawEllipse(8, 4, 8, 8);
+    painter.drawArc(4, 12, 16, 12, 0, 180 * 16);
+    return QIcon(pixmap);
+}
+
+QIcon createAudioDeviceIcon()
+{
+    QPixmap pixmap(24, 24);
+    pixmap.fill(Qt::transparent);
+    QPainter painter(&pixmap);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setPen(QPen(Qt::black, 2));
+    painter.drawRect(8, 6, 8, 12);
+    painter.drawLine(6, 10, 8, 10);
+    painter.drawLine(6, 14, 8, 14);
+    painter.drawLine(16, 10, 18, 10);
+    painter.drawLine(16, 14, 18, 14);
+    return QIcon(pixmap);
+}
+
+QIcon createStreamIcon()
+{
+    QPixmap pixmap(24, 24);
+    pixmap.fill(Qt::transparent);
+    QPainter painter(&pixmap);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setPen(QPen(Qt::black, 2));
+    QPolygon triangle;
+    triangle << QPoint(6, 6) << QPoint(18, 12) << QPoint(6, 18);
+    painter.drawPolygon(triangle);
+    return QIcon(pixmap);
+}
+
+QIcon createChatIcon()
+{
+    QPixmap pixmap(24, 24);
+    pixmap.fill(Qt::transparent);
+    QPainter painter(&pixmap);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setPen(QPen(Qt::black, 2));
+    painter.drawRoundedRect(4, 4, 16, 12, 2, 2);
+    QPolygon tail;
+    tail << QPoint(8, 16) << QPoint(12, 20) << QPoint(12, 16);
+    painter.drawPolygon(tail);
+    return QIcon(pixmap);
+}
+
+QIcon createRecordIcon()
+{
+    QPixmap pixmap(24, 24);
+    pixmap.fill(Qt::transparent);
+    QPainter painter(&pixmap);
+    painter.setRenderHint(QPainter::Antialiasing);
+    painter.setPen(QPen(Qt::red, 2));
+    painter.setBrush(QBrush(Qt::red));
+    painter.drawEllipse(6, 6, 12, 12);
+    return QIcon(pixmap);
+}
+
+} // namespace IconUtils

+ 56 - 0
utils/iconutils.h

@@ -0,0 +1,56 @@
+#ifndef ICONUTILS_H
+#define ICONUTILS_H
+
+#include <QIcon>
+#include <QPixmap>
+#include <QPainter>
+#include <QPolygon>
+#include <QPen>
+
+namespace IconUtils {
+
+/**
+ * @brief 创建设置图标
+ * @return QIcon 设置图标
+ */
+QIcon createSettingsIcon();
+
+/**
+ * @brief 创建搜索图标
+ * @return QIcon 搜索图标
+ */
+QIcon createSearchIcon();
+
+/**
+ * @brief 创建用户图标
+ * @return QIcon 用户图标
+ */
+QIcon createUserIcon();
+
+/**
+ * @brief 创建音频设备图标
+ * @return QIcon 音频设备图标
+ */
+QIcon createAudioDeviceIcon();
+
+/**
+ * @brief 创建推流图标
+ * @return QIcon 推流图标
+ */
+QIcon createStreamIcon();
+
+/**
+ * @brief 创建聊天图标
+ * @return QIcon 聊天图标
+ */
+QIcon createChatIcon();
+
+/**
+ * @brief 创建录音图标
+ * @return QIcon 录音图标
+ */
+QIcon createRecordIcon();
+
+} // namespace IconUtils
+
+#endif // ICONUTILS_H