This commit is contained in:
2026-06-14 15:54:35 +08:00
commit 3caeb07e54
2804 changed files with 373231 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
//
// Created by Administrator on 2025/3/4.
//
#ifndef AIRI_DESKTOPGRIL_AUDIOPAGE_H
#define AIRI_DESKTOPGRIL_AUDIOPAGE_H
#include "BasePage.h"
#include "ElaPushButton.h"
class ElaComboBox;
class ElaSpinBox;
class ElaProgressBar;
class ElaPushButton;
class AudioPage : public BasePage
{
Q_OBJECT
public:
Q_INVOKABLE explicit AudioPage(QWidget* parent = nullptr);
~AudioPage() override;
private:
ElaComboBox* audioInputDeviceComboBox = nullptr;
ElaSpinBox* audioInputSpinBox = nullptr;
ElaProgressBar* audioInputProgressBar = nullptr;
ElaPushButton* audioAutoThresholdStartButton = nullptr;
ElaPushButton* audioManualThresholdStartButton = nullptr;
ElaPushButton* testAudioPlayButton = nullptr;
};
#endif //AIRI_DESKTOPGRIL_AUDIOPAGE_H
+21
View File
@@ -0,0 +1,21 @@
//
// Created by Administrator on 2025/2/27.
//
#ifndef AIRI_DESKTOPGRIL_BASEPAGE_H
#define AIRI_DESKTOPGRIL_BASEPAGE_H
#include <ElaScrollPage.h>
class QVBoxLayout;
class BasePage : public ElaScrollPage
{
Q_OBJECT
public:
Q_INVOKABLE explicit BasePage(QWidget* parent = nullptr);
~BasePage();
protected:
void createCustomWidget(QString desText);
};
#endif //AIRI_DESKTOPGRIL_BASEPAGE_H
+23
View File
@@ -0,0 +1,23 @@
//
// Created by Administrator on 2025/2/28.
//
#ifndef AIRI_DESKTOPGRIL_HOMEPAGE_H
#define AIRI_DESKTOPGRIL_HOMEPAGE_H
#include "BasePage.h"
class ElaMenu;
class HomePage : public BasePage
{
Q_OBJECT
public:
Q_INVOKABLE explicit HomePage(QWidget* parent = nullptr);
~HomePage();
Q_SIGNALS:
Q_SIGNAL void audioNavigation();
Q_SIGNAL void modelShopNavigation();
};
#endif //AIRI_DESKTOPGRIL_HOMEPAGE_H
+41
View File
@@ -0,0 +1,41 @@
//
// Created by Administrator on 2025/4/1.
//
/**
* @brief 模型页面
* 暂时只做最简单功能切换模型
*/
#pragma once
#include "BasePage.h"
#include "ElaPushButton.h"
#include "ElaLineEdit.h"
#include "ElaComboBox.h"
#include "ElaSlider.h"
#include <QUrl>
#include <utility>
class ModelPage final : public BasePage
{
Q_OBJECT
public:
Q_INVOKABLE explicit ModelPage(QWidget* parent = nullptr);
std::pair<QString, QString> splitPath(const QString& fullPath);
~ModelPage() override;
private:
// 设置当前模型
ElaLineEdit* modelUrlEdit = nullptr; /// 模型Url 编辑框
ElaPushButton* modelChoosePushButton = nullptr; /// 选择模型按钮
ElaPushButton* modelUsePushButton = nullptr; /// 使用模型按钮
ElaSlider* modelSlider = nullptr; /// 滑块(用于设置模型实时大小)
QUrl modelFileUrl;
QString modelFilePathFirst;
QString modelFilePathSecond;
};
+39
View File
@@ -0,0 +1,39 @@
//
// Created by Administrator on 2025/3/2.
//
#pragma once
#include "BasePage.h"
#include "ElaPushButton.h"
#include "ElaLineEdit.h"
class ElaPushButton;
class ElaLineEdit;
class NetWorkPage final : public BasePage
{
Q_OBJECT
public:
Q_INVOKABLE explicit NetWorkPage(QWidget* parent = nullptr);
~NetWorkPage() override;
private:
void initUI();
void initWebSocketClient();
private:
// websocket 控件
ElaPushButton* websocketPushButton = nullptr;
ElaLineEdit* websocketLineEdit = nullptr;
// 连接测试
ElaPushButton* connectTestPushButton = nullptr;
// 连接
ElaPushButton* connectPushButton = nullptr;
// 断开
ElaPushButton* disconnectPushButton = nullptr;
// 发送测试按钮
ElaPushButton* sendTestPushButton = nullptr;
};
+30
View File
@@ -0,0 +1,30 @@
//
// Created by Administrator on 2025/3/30.
//
#ifndef YOSUGA_RENDERPAGE_H
#define YOSUGA_RENDERPAGE_H
#include "BasePage.h"
#include "ElaPushButton.h"
#include "ElaLineEdit.h"
#include "ElaComboBox.h"
class RenderPage : public BasePage
{
Q_OBJECT
public:
Q_INVOKABLE explicit RenderPage(QWidget* parent = nullptr);
~RenderPage();
private:
// 帧率设置
ElaComboBox* frameRateComboBox = nullptr;
};
#endif //YOSUGA_RENDERPAGE_H
+65
View File
@@ -0,0 +1,65 @@
//
// Created by Administrator on 2025/1/21.
//
#pragma once
#include <ElaWidget.h>
#include <ElaWindow.h>
#include <ElaPushButton.h>
#include <ElaScrollPage.h>
#include <QStackedWidget>
#include "HomePage.h"
#include "NetworkPage.h"
#include "UISetting.h"
#include "AudioPage.h"
#include "RenderPage.h"
#include "ModelPage.h"
class Setting : public ElaWindow
{
Q_OBJECT
public:
explicit Setting(QWidget *parent = nullptr);
~Setting();
private:
/**
* 初始化所有页面指针
* @author : Misaki
*/
void initPages();
/**
* 初始化导航栏
* @author : Misaki
*/
void initNavigationBar();
/**
* 初始化上下文切换
* @author : Misaki
*/
void initContent();
private slots:
void toggleTheme();
private:
// 页面指针
HomePage *homePage;
NetWorkPage *networkPage;
UISetting *uiSetting;
AudioPage *audioPage;
RenderPage *renderPage;
ModelPage *modelPage;
// 节点键值
QString basePageKey;
//
ElaPushButton *themeToggleButton;
};
+26
View File
@@ -0,0 +1,26 @@
//
// Created by Administrator on 2025/3/2.
//
#pragma once
#include "BasePage.h"
class ElaRadioButton;
class ElaToggleSwitch;
class ElaComboBox;
class UISetting : public BasePage
{
Q_OBJECT
public:
Q_INVOKABLE explicit UISetting(QWidget* parent = nullptr);
~UISetting();
private:
ElaComboBox* _themeComboBox = nullptr;
ElaToggleSwitch* _micaSwitchButton = nullptr;
ElaToggleSwitch* _logSwitchButton = nullptr;
ElaRadioButton* _minimumButton = nullptr;
ElaRadioButton* _compactButton = nullptr;
ElaRadioButton* _maximumButton = nullptr;
ElaRadioButton* _autoButton = nullptr;
};
+132
View File
@@ -0,0 +1,132 @@
//
// Created by Administrator on 2025/3/4.
//
#include "AudioPage.h"
#include <QHBoxLayout>
#include "ElaComboBox.h"
#include "ElaPlainTextEdit.h"
#include "ElaProgressBar.h"
#include "ElaScrollPageArea.h"
#include "ElaSlider.h"
#include "ElaSpinBox.h"
#include "ElaText.h"
#include "ElaMessageBar.h"
#include "AudioInput.h"
#include "AudioOutput.h"
#include "TextRenderer.h"
#include "LAppLive2DManager.hpp"
AudioPage::AudioPage(QWidget* parent)
: BasePage(parent)
{
// 预览窗口标题
setWindowTitle("AudioPage");
audioInputDeviceComboBox = new ElaComboBox(this);
audioInputDeviceComboBox->setToolTip("选择可用的录音设备");
QStringList comboList = AudioInput::getAvailableAudioInputDevices();
audioInputDeviceComboBox->addItems(comboList);
ElaScrollPageArea* comboBoxArea = new ElaScrollPageArea(this);
QHBoxLayout* comboBoxLayout = new QHBoxLayout(comboBoxArea);
ElaText* comboBoxText = new ElaText("录音设备", this);
comboBoxText->setTextPixelSize(15);
comboBoxLayout->addWidget(comboBoxText);
comboBoxLayout->addWidget(audioInputDeviceComboBox);
comboBoxLayout->addStretch();
comboBoxLayout->addSpacing(10);
connect(audioInputDeviceComboBox, &ElaComboBox::currentTextChanged, [this](const QString& text) {
AudioInput::getInstance()->setAudioInputDevice(text);
ElaMessageBar::success(ElaMessageBarType::TopRight, "音频设置", "成功设置 " + text + " 为当前录音设备", 800.0, this);
});
audioInputSpinBox = new ElaSpinBox(this); // SpinBox
audioInputSpinBox->setRange(0, 10000);
audioInputProgressBar = new ElaProgressBar(this);
audioInputProgressBar->setRange(0, 10000);
// 关闭ProgressBar的百分比显示
audioInputProgressBar->setTextVisible(false);
// 将SpinBox和ProgressBar的数值相互绑定
connect(audioInputSpinBox, QOverload<int>::of(&ElaSpinBox::valueChanged), [this](int value) {
audioInputProgressBar->setValue(value);
});
connect(audioInputProgressBar, QOverload<int>::of(&ElaProgressBar::valueChanged), [this](int value) {
audioInputSpinBox->setValue(value);
});
// 绑定实时录音阈值到ProgressBar,同时归一到0~1000范围内
connect(AudioInput::getInstance(), &AudioInput::rmsRealValue, [this](const qreal value) {
audioInputProgressBar->setValue(value);
});
// 当计算完成最优阈值
connect(AudioInput::getInstance(), &AudioInput::thresholdCalculated, [this](qreal value) {
ElaMessageBar::success(ElaMessageBarType::TopRight, "音频设置", "自动计算出的最优阈值为:" + QString::number(value), 1000, this);
// AudioInput会自动设置计算出的最优阈值
});
audioAutoThresholdStartButton = new ElaPushButton("自动最优阈值", this);
audioAutoThresholdStartButton->setToolTip("点击后保持当前环境音5秒,自动计算出最合适的静音检测阈值");
connect(audioAutoThresholdStartButton, &ElaPushButton::clicked, [=]() {
AudioInput::getInstance()->startAutoThresholdClu(5000);
qDebug("开始计算最优阈值");
});
audioManualThresholdStartButton = new ElaPushButton("手动设置阈值", this);
audioManualThresholdStartButton->setToolTip("如果你觉得自动计算的不准的话");
connect(audioManualThresholdStartButton, &ElaPushButton::clicked, [this]() {
AudioInput::getInstance()->setSilenceThreshold(audioInputSpinBox->value());
ElaMessageBar::success(ElaMessageBarType::TopRight, "音频设置", "手动设置的阈值为:" + QString::number(audioInputSpinBox->value()), 1000, this);
});
ElaScrollPageArea* audioInputProgressBarArea = new ElaScrollPageArea(this);
QHBoxLayout* audioInputProgressBarLayout = new QHBoxLayout(audioInputProgressBarArea);
ElaText* audioInputProgressBarText = new ElaText("静音检测阈值", this);
audioInputProgressBarText->setToolTip("测试当前环境的静音阈值,用于对话中的静音检测");
audioInputProgressBarText->setTextPixelSize(15);
audioInputProgressBarLayout->addWidget(audioInputProgressBarText);
audioInputProgressBarLayout->addWidget(audioInputProgressBar, 1);
audioInputProgressBarLayout->addWidget(audioInputSpinBox);
audioInputProgressBarLayout->addStretch(); // 添加弹性空间将后续控件推到右侧
audioInputProgressBarLayout->addWidget(audioAutoThresholdStartButton);
audioInputProgressBarLayout->addWidget(audioManualThresholdStartButton);
audioInputProgressBarLayout->addStretch();
audioInputProgressBarLayout->addSpacing(10);
testAudioPlayButton = new ElaPushButton("播放测试", this);
testAudioPlayButton->setToolTip("播放一段测试音频来检测播放功能是否正常,注意观察模型嘴唇以及文字下落动画");
ElaScrollPageArea* testAudioArea = new ElaScrollPageArea(this);
QHBoxLayout* testAudioLayout = new QHBoxLayout(testAudioArea);
ElaText* testAudioText = new ElaText("测试", this);
testAudioText->setTextPixelSize(15);
testAudioLayout->addWidget(testAudioText);
testAudioLayout->addStretch(); // 添加弹性空间将后续控件推到右侧
testAudioLayout->addWidget(testAudioPlayButton);
testAudioLayout->addSpacing(10);
connect(testAudioPlayButton, &ElaPushButton::clicked, [this]() {
const QString text = "あれアイリーじゃないよ!急にいなくなるからどこに行ったのかと思えば~";
constexpr float duration = 6.0f; // 音频时长
TextRenderer::getInstance()->addText(text, 40.0f, QColor("#FF69B4"), duration);
LAppLive2DManager::GetInstance()->StartLipSync("Resources/TestFiles/test.wav");
AudioOutput::getInstance()->playUrl(QUrl("Resources/TestFiles/test.wav"));
});
QWidget* centralWidget = new QWidget(this);
centralWidget->setWindowTitle("音频设置");
QVBoxLayout* centerLayout = new QVBoxLayout(centralWidget);
centerLayout->addWidget(comboBoxArea);
centerLayout->addWidget(audioInputProgressBarArea);
centerLayout->addWidget(testAudioArea);
centerLayout->addStretch();
centerLayout->setContentsMargins(0, 0, 0, 0);
addCentralWidget(centralWidget, true, true, 0);
}
AudioPage::~AudioPage()
{
}
+89
View File
@@ -0,0 +1,89 @@
//
// Created by Administrator on 2025/2/27.
//
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "BasePage.h"
#include "ElaMenu.h"
#include "ElaText.h"
#include "ElaTheme.h"
#include "ElaToolButton.h"
BasePage::BasePage(QWidget* parent)
: ElaScrollPage(parent)
{
connect(eTheme, &ElaTheme::themeModeChanged, this, [=, this]() {
if (!parent)
{
update();
}
});
}
BasePage::~BasePage()
{
}
void BasePage::createCustomWidget(QString desText)
{
// 顶部元素
QWidget* customWidget = new QWidget(this);
ElaText* subTitleText = new ElaText(this);
subTitleText->setText("https://github.com/Liniyous/ElaWidgetTools");
subTitleText->setTextInteractionFlags(Qt::TextSelectableByMouse);
subTitleText->setTextPixelSize(11);
ElaToolButton* documentationButton = new ElaToolButton(this);
documentationButton->setFixedHeight(35);
documentationButton->setIsTransparent(false);
documentationButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
//_toolButton->setPopupMode(QToolButton::MenuButtonPopup);
documentationButton->setText("Documentation");
documentationButton->setElaIcon(ElaIconType::FileDoc);
ElaMenu* documentationMenu = new ElaMenu(this);
documentationMenu->addElaIconAction(ElaIconType::CardsBlank, "CardsBlank");
documentationMenu->addElaIconAction(ElaIconType::EarthAmericas, "EarthAmericas");
documentationButton->setMenu(documentationMenu);
ElaToolButton* sourceButton = new ElaToolButton(this);
sourceButton->setFixedHeight(35);
sourceButton->setIsTransparent(false);
sourceButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
sourceButton->setText("Source");
sourceButton->setElaIcon(ElaIconType::NfcSymbol);
ElaMenu* sourceMenu = new ElaMenu(this);
sourceMenu->addElaIconAction(ElaIconType::FireBurner, "FireBurner");
sourceMenu->addElaIconAction(ElaIconType::Galaxy, "Galaxy~~~~");
sourceButton->setMenu(sourceMenu);
ElaToolButton* themeButton = new ElaToolButton(this);
themeButton->setFixedSize(35, 35);
themeButton->setIsTransparent(false);
themeButton->setElaIcon(ElaIconType::MoonStars);
connect(themeButton, &ElaToolButton::clicked, this, [=]() {
eTheme->setThemeMode(eTheme->getThemeMode() == ElaThemeType::Light ? ElaThemeType::Dark : ElaThemeType::Light);
});
QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addWidget(documentationButton);
buttonLayout->addSpacing(5);
buttonLayout->addWidget(sourceButton);
buttonLayout->addStretch();
buttonLayout->addWidget(themeButton);
buttonLayout->addSpacing(15);
ElaText* descText = new ElaText(this);
descText->setText(desText);
descText->setTextPixelSize(13);
QVBoxLayout* topLayout = new QVBoxLayout(customWidget);
topLayout->setContentsMargins(0, 0, 0, 0);
topLayout->addWidget(subTitleText);
topLayout->addSpacing(5);
topLayout->addLayout(buttonLayout);
topLayout->addSpacing(5);
topLayout->addWidget(descText);
setCustomWidget(customWidget);
}
+154
View File
@@ -0,0 +1,154 @@
//
// Created by Administrator on 2025/2/28.
//
#include "HomePage.h"
#include <QDebug>
#include <QDesktopServices>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QPainter>
#include <QVBoxLayout>
#include "ElaAcrylicUrlCard.h"
#include "ElaFlowLayout.h"
#include "ElaImageCard.h"
#include "ElaMenu.h"
#include "ElaMessageBar.h"
#include "ElaNavigationRouter.h"
#include "ElaPopularCard.h"
#include "ElaScrollArea.h"
#include "ElaText.h"
#include "ElaToolTip.h"
HomePage::HomePage(QWidget* parent)
: BasePage(parent)
{
// 预览窗口标题
setWindowTitle("Home");
setTitleVisible(false);
setContentsMargins(2, 2, 0, 0);
// 标题卡片区域
ElaText* desText = new ElaText("UI By ElaWidgetTools", this);
desText->setTextPixelSize(18);
ElaText* titleText = new ElaText("Yosuga!", this);
titleText->setTextPixelSize(35);
QVBoxLayout* titleLayout = new QVBoxLayout();
titleLayout->setContentsMargins(30, 60, 0, 0);
titleLayout->addWidget(desText);
titleLayout->addWidget(titleText);
ElaImageCard* backgroundCard = new ElaImageCard(this);
backgroundCard->setBorderRadius(10);
backgroundCard->setFixedHeight(400);
backgroundCard->setMaximumAspectRatio(1.7);
backgroundCard->setCardImage(QImage("Resources/Pic/Airi/Airi_Background.png"));
ElaAcrylicUrlCard* urlCard1 = new ElaAcrylicUrlCard(this);
urlCard1->setCardPixmapSize(QSize(62, 62));
urlCard1->setFixedSize(195, 225);
urlCard1->setTitlePixelSize(17);
urlCard1->setTitleSpacing(25);
urlCard1->setSubTitleSpacing(13);
urlCard1->setUrl("https://github.com/Misakityan/Yosuga");
urlCard1->setCardPixmap(QPixmap("Resources/Pic/Others/img.png"));
urlCard1->setTitle("Yosuga Github");
urlCard1->setSubTitle("Star++!");
ElaToolTip* urlCard1ToolTip = new ElaToolTip(urlCard1);
urlCard1ToolTip->setToolTip("点击前往本项目GitHub");
ElaAcrylicUrlCard* urlCard2 = new ElaAcrylicUrlCard(this);
urlCard2->setCardPixmapSize(QSize(62, 62));
urlCard2->setFixedSize(195, 225);
urlCard2->setTitlePixelSize(17);
urlCard2->setTitleSpacing(25);
urlCard2->setSubTitleSpacing(13);
urlCard2->setUrl("https://space.bilibili.com/140315806");
urlCard2->setCardPixmap(QPixmap("Resources/Pic/Others/Misaki.jpg"));
urlCard2->setTitle("Misaki");
urlCard2->setSubTitle("1841738040@qq.com");
ElaToolTip* urlCard2ToolTip = new ElaToolTip(urlCard2);
urlCard2ToolTip->setToolTip("点击前往 Misaki 的个人主页");
ElaScrollArea* cardScrollArea = new ElaScrollArea(this);
cardScrollArea->setWidgetResizable(true);
cardScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
cardScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
cardScrollArea->setIsGrabGesture(true, 0);
cardScrollArea->setIsOverShoot(Qt::Horizontal, true);
QWidget* cardScrollAreaWidget = new QWidget(this);
cardScrollAreaWidget->setStyleSheet("background-color:transparent;");
cardScrollArea->setWidget(cardScrollAreaWidget);
QHBoxLayout* urlCardLayout = new QHBoxLayout();
urlCardLayout->setSpacing(15);
urlCardLayout->setContentsMargins(30, 0, 0, 6);
urlCardLayout->addWidget(urlCard1);
urlCardLayout->addWidget(urlCard2);
urlCardLayout->addStretch();
QVBoxLayout* cardScrollAreaWidgetLayout = new QVBoxLayout(cardScrollAreaWidget);
cardScrollAreaWidgetLayout->setContentsMargins(0, 0, 0, 0);
cardScrollAreaWidgetLayout->addStretch();
cardScrollAreaWidgetLayout->addLayout(urlCardLayout);
QVBoxLayout* backgroundLayout = new QVBoxLayout(backgroundCard);
backgroundLayout->setContentsMargins(0, 0, 0, 0);
backgroundLayout->addLayout(titleLayout);
backgroundLayout->addWidget(cardScrollArea);
// 推荐卡片
ElaText* flowText = new ElaText("快速转到", this);
flowText->setTextPixelSize(20);
QHBoxLayout* flowTextLayout = new QHBoxLayout();
flowTextLayout->setContentsMargins(33, 0, 0, 0);
flowTextLayout->addWidget(flowText);
// ElaFlowLayout
// 模型商店卡片
ElaPopularCard* ModeShopCard = new ElaPopularCard(this);
connect(ModeShopCard, &ElaPopularCard::popularCardButtonClicked, this, [=, this]() {
Q_EMIT modelShopNavigation();
});
ModeShopCard->setCardPixmap(QPixmap("Resources/Pic/Others/Live2D.png"));
ModeShopCard->setTitle("模型设置");
ModeShopCard->setSubTitle("属于你的Live2D模型");
ModeShopCard->setInteractiveTips("By Misaki");
ModeShopCard->setDetailedText("选择你喜欢的Live2D模型");
// 音频设置卡片
ElaPopularCard* AudioSettingCard = new ElaPopularCard(this);
connect(AudioSettingCard, &ElaPopularCard::popularCardButtonClicked, this, [=, this]() {
Q_EMIT audioNavigation();
});
AudioSettingCard->setTitle("音频设置");
AudioSettingCard->setSubTitle("录音与播放的设置");
AudioSettingCard->setCardPixmap(QPixmap("Resources/Pic/control/AutomationProperties.png"));
AudioSettingCard->setInteractiveTips("By Misaki");
AudioSettingCard->setDetailedText("自定义音频与播放的相关设定,打造最舒适的交流环境。");
ElaFlowLayout* flowLayout = new ElaFlowLayout(0, 5, 5);
flowLayout->setContentsMargins(30, 0, 0, 0);
flowLayout->setIsAnimation(true);
flowLayout->addWidget(ModeShopCard);
flowLayout->addWidget(AudioSettingCard);
QWidget* centralWidget = new QWidget(this);
centralWidget->setWindowTitle("Home");
QVBoxLayout* centerVLayout = new QVBoxLayout(centralWidget);
centerVLayout->setSpacing(0);
centerVLayout->setContentsMargins(0, 0, 0, 0);
centerVLayout->addWidget(backgroundCard);
centerVLayout->addSpacing(20);
centerVLayout->addLayout(flowTextLayout);
centerVLayout->addSpacing(10);
centerVLayout->addLayout(flowLayout);
centerVLayout->addStretch();
addCentralWidget(centralWidget);
}
HomePage::~HomePage()
{
}
+191
View File
@@ -0,0 +1,191 @@
//
// Created by Administrator on 2025/4/1.
//
#include "ModelPage.h"
#include <QFileDialog>
#include <QHBoxLayout>
#include "ElaMessageBar.h"
#include "ElaScrollPageArea.h"
#include "ElaText.h"
#include <QtConcurrent>
#include <QOpenGLContext>
#include <QOffscreenSurface>
#include <QFutureWatcher>
#include "LAppLive2DManager.hpp"
ModelPage::ModelPage(QWidget *parent)
: BasePage(parent) {
// 预览窗口标题
setWindowTitle("ModelPage");
modelUrlEdit = new ElaLineEdit(this); // 模型Url Edit
modelUrlEdit->setFixedWidth(300);
modelUrlEdit->setPlaceholderText("用于显示当前的模型Url");
modelChoosePushButton = new ElaPushButton("选择模型", this);
modelChoosePushButton->setToolTip("选择.model3.json结尾的文件");
modelUsePushButton = new ElaPushButton("使用模型", this);
modelUsePushButton->setToolTip("使用选择的模型或Url对应的模型");
ElaScrollPageArea *modelSetArea = new ElaScrollPageArea(this);
QHBoxLayout *modelSetLayout = new QHBoxLayout(modelSetArea);
ElaText *modelSetText = new ElaText("模型设置", this);
modelSetText->setTextPixelSize(15);
modelSetLayout->addWidget(modelSetText);
modelSetLayout->addWidget(modelUrlEdit);
modelSetLayout->addStretch();
modelSetLayout->addWidget(modelChoosePushButton);
modelSetLayout->addWidget(modelUsePushButton);
modelSetLayout->addSpacing(10);
// 创建滑块控件和标签
ElaText *modelSizeText = new ElaText("模型大小比例设置", this);
modelSizeText->setToolTip("实时调整模型大小");
modelSizeText->setTextPixelSize(15);
modelSlider = new ElaSlider(this); // 滑块(用于设置模型实时大小)
modelSlider->setRange(0, 99); // 设置范围
modelSlider->setValue(85); // 设置默认值
modelSlider->setOrientation(Qt::Horizontal); // 水平方向
// 创建独立的区域容器
ElaScrollPageArea *modelSliderArea = new ElaScrollPageArea(this);
QHBoxLayout *modelSliderLayout = new QHBoxLayout(modelSliderArea);
// 添加到布局(加一个标签显示数值)
ElaText *modelSliderValueText = new ElaText("85%", this);
modelSliderValueText->setTextPixelSize(14);
connect(modelSlider, &ElaSlider::valueChanged, this, [modelSliderValueText](const int value){
modelSliderValueText->setText(QString("%1%").arg(value + 1));
LAppLive2DManager::GetInstance()->ModelSizeChange(100 - value); // 实时更新模型大小
});
modelSliderLayout->addWidget(modelSizeText);
modelSliderLayout->addWidget(modelSlider);
modelSliderLayout->addWidget(modelSliderValueText);
modelSliderLayout->addStretch(); // 让内容靠左
connect(modelChoosePushButton, &ElaPushButton::clicked, this, [this]() {
// 创建对话框对象(使用 heap 分配,由 Qt 对象树管理内存)
auto *fileDialog = new QFileDialog(this);
fileDialog->setWindowTitle("选择模型文件");
fileDialog->setNameFilter("Live2D Model (*.model3.json)");
// 设置初始目录
const QString exeDir = QCoreApplication::applicationDirPath(); // 获取当前exe所在目录的本地路径
fileDialog->setDirectory(exeDir); // 设置初始目录为当前 exe 所在目录
// 连接信号:当用户选中文件并点击打开时
connect(fileDialog, &QFileDialog::fileSelected, this, [this, fileDialog](const QString &file) {
modelFileUrl = QUrl::fromLocalFile(file);
if (!modelFileUrl.isEmpty()) {
const QString t = modelFileUrl.toLocalFile();
const std::pair<QString, QString> path = this->splitPath(t);
this->modelFilePathFirst = path.first;
this->modelFilePathSecond = path.second;
this->modelUrlEdit->setText(t);
ElaMessageBar::success(ElaMessageBarType::BottomRight, "模型设置", "模型选择成功", 2000, this);
}
// 用完即弃,自动清理内存
fileDialog->deleteLater();
});
// 处理取消的情况(防止内存泄漏)
connect(fileDialog, &QFileDialog::rejected, fileDialog, &QObject::deleteLater);
// 显示对话框(非阻塞,不会卡住主界面)
fileDialog->open();
});
connect(modelUsePushButton, &ElaPushButton::clicked, this, [this]() {
// 模型使用
if (modelFileUrl.isEmpty()) {
ElaMessageBar::information(ElaMessageBarType::BottomRight, "模型设置", "似乎并没有选择模型", 800.0, this);
return;
}
// UI 状态设置为加载中
modelUsePushButton->setEnabled(false); // 禁用使用按钮
modelUsePushButton->setText("加载中"); // 修改按钮文本
modelChoosePushButton->setEnabled(false); // 禁用选择按钮
// 获取路径字符串 (必须按值传递给lambda)
std::string dir = this->modelFilePathFirst.toStdString();
std::string filename = this->modelFilePathSecond.toStdString();
// 启动异步任务
QFuture<LAppModel *> future = QtConcurrent::run([dir, filename]() -> LAppModel * {
// 以下代码在子线程执行
// 创建临时 OpenGL 上下文
auto *context = new QOpenGLContext();
// 关键点:设置与全局共享上下文共享 (这样主线程才能看到纹理)
context->setShareContext(QOpenGLContext::globalShareContext());
if (!context->create()) {
delete context;
return nullptr;
}
// 创建离屏表面 (因为子线程没有窗口,需要一个假的绘制表面)
auto *surface = new QOffscreenSurface();
surface->setFormat(context->format());
surface->create();
// 绑定上下文
if (!context->makeCurrent(surface)) {
delete surface;
delete context;
return nullptr;
}
// 执行真正的耗时加载
// 调用在 Manager 里新写的函数
LAppModel *model = LAppLive2DManager::GetInstance()->LoadModelInstance(dir, filename);
// 清理子线程资源
context->doneCurrent();
delete surface;
delete context;
return model;
});
// 监控任务结束
auto *watcher = new QFutureWatcher<LAppModel *>();
connect(watcher, &QFutureWatcher<LAppModel *>::finished, this, [this, watcher]() {
// 下面的代码在主线程中执行
LAppModel *newModel = watcher->result();
if (newModel) {
// 调用挂载函数,瞬间完成切换
LAppLive2DManager::GetInstance()->MountLoadedModel(newModel);
ElaMessageBar::success(ElaMessageBarType::BottomRight, "成功", "模型加载完成", 2000, this);
} else {
ElaMessageBar::error(ElaMessageBarType::BottomRight, "错误", "模型加载失败 (OpenGL环境异常)", 2000, this);
}
// 恢复 UI
modelUsePushButton->setEnabled(true);
modelUsePushButton->setText("使用模型");
modelChoosePushButton->setEnabled(true);
watcher->deleteLater();
});
// 开始监控
watcher->setFuture(future);
});
QWidget *centralWidget = new QWidget(this);
centralWidget->setWindowTitle("模型设置");
QVBoxLayout *centerLayout = new QVBoxLayout(centralWidget);
centerLayout->addWidget(modelSetArea);
centerLayout->addWidget(modelSliderArea);
centerLayout->addStretch();
centerLayout->setContentsMargins(0, 0, 0, 0);
addCentralWidget(centralWidget, true, true, 0);
}
// 返回 pair<目录路径, 文件名>
std::pair<QString, QString> ModelPage::splitPath(const QString &fullPath) {
const QFileInfo fileInfo(fullPath);
// 获取目录部分(自动处理末尾斜杠)
QString dirPath = fileInfo.dir().absolutePath() + "/";
// 获取文件名部分(如果是目录则返回空)
QString fileName = fileInfo.fileName();
return {dirPath, fileName};
}
ModelPage::~ModelPage() {
}
+186
View File
@@ -0,0 +1,186 @@
//
// Created by Administrator on 2025/3/2.
//
#include "NetworkPage.h"
#include <QHBoxLayout>
#include "ElaScrollPageArea.h"
#include "ElaText.h"
#include "ElaMessageBar.h"
#include "websocketmanager.h"
#include "NetWorkDO.h"
#include <QFile>
NetWorkPage::NetWorkPage(QWidget* parent)
: BasePage(parent)
{
// 预览窗口标题
setWindowTitle("NetworkPage");
this->initUI(); // 初始化UI
this->initWebSocketClient(); // 初始化websocket客户端(主要是相关的信号与槽)
}
NetWorkPage::~NetWorkPage()
{
}
void NetWorkPage::initUI() {
// websocket UI
websocketPushButton = new ElaPushButton("设定",this);
websocketPushButton->setToolTip("设定服务端WebSocket地址");
websocketLineEdit = new ElaLineEdit(this);
websocketLineEdit->setPlaceholderText("请输入服务端WebSocket地址");
websocketLineEdit->setFixedWidth(300); // 设置websocketLineEdit框的宽度
ElaScrollPageArea* websocketToggleSwitchArea = new ElaScrollPageArea(this);
QHBoxLayout* websocketToggleSwitchLayout = new QHBoxLayout(websocketToggleSwitchArea);
ElaText* websocketToggleSwitchText = new ElaText("服务端WebSocket地址:", this);
websocketToggleSwitchText->setTextPixelSize(15);
websocketToggleSwitchLayout->addWidget(websocketToggleSwitchText);
websocketToggleSwitchLayout->addWidget(websocketLineEdit);
websocketToggleSwitchLayout->addStretch();
websocketToggleSwitchLayout->addWidget(websocketPushButton);
websocketToggleSwitchLayout->addSpacing(10);
// 连通测试按钮
connectTestPushButton = new ElaPushButton("连通测试",this);
connectTestPushButton->setToolTip("测试与服务器连通性(如果成功连通会自动连上服务器)");
connectPushButton = new ElaPushButton("连接",this);
disconnectPushButton = new ElaPushButton("断开",this);
sendTestPushButton = new ElaPushButton("发送测试",this);
ElaScrollPageArea* connectTestArea = new ElaScrollPageArea(this); // 创建一个滚动页面
QHBoxLayout* connectTestLayout = new QHBoxLayout(connectTestArea);
connectTestLayout->addWidget(connectTestPushButton); // 将连通测试按钮添加到布局中
connectTestLayout->addStretch(); // 添加一个空格
connectTestLayout->addWidget(sendTestPushButton); // 将发送测试按钮添加到布局中
connectTestLayout->addWidget(disconnectPushButton); // 将断开按钮添加到布局中
connectTestLayout->addWidget(connectPushButton); // 将连接按钮添加到布局中
connectTestLayout->addSpacing(10);
// 添加到布局
QWidget* centralWidget = new QWidget(this); // 中心部件
centralWidget->setWindowTitle("连接设置"); // 中心部件标题
QVBoxLayout* centerLayout = new QVBoxLayout(centralWidget); // 中心部件布局
centerLayout->addWidget(websocketToggleSwitchArea); // 将websocketToggleSwitchArea添加到布局中
centerLayout->addWidget(connectTestArea); // 将connectTestArea添加到布局中
centerLayout->addStretch();
centerLayout->setContentsMargins(0, 0, 0, 0); // 设置布局的边距
addCentralWidget(centralWidget, true, true, 0); // 添加中心部件
}
void NetWorkPage::initWebSocketClient() {
auto* client = WebSocketClient::getInstance(); // 获取单例实例(设置一个默认地址)
auto* netDO = NetworkDO::getInstance();
// 注入:将底层发送能力赋予 NetworkDO
netDO->registerSender([client](const QString& type, const QJsonObject& data){
client->sendJson(type, data);
});
// 监听:底层收到数据 -> NetworkDO 解析
connect(client, &WebSocketClient::jsonReceived,
netDO, &NetworkDO::onDataReceived);
// 连接成功的处理
connect(client, &WebSocketClient::connected, this, [this]() {
ElaMessageBar::success(ElaMessageBarType::TopRight, "WebSocket", "连接成功", 800.0, this);
});
// 连接失败的处理
connect(client, &WebSocketClient::error, this, [this](const QString& errorMsg) {
ElaMessageBar::error(ElaMessageBarType::TopLeft, "WebSocket错误", errorMsg, 1500.0, this);
});
// 断开连接的处理
connect(client, &WebSocketClient::disconnected, this, [this]() {
ElaMessageBar::information(ElaMessageBarType::BottomRight, "WebSocket", "连接已断开", 800.0, this);
});
// 接收数据处理
connect(client, &WebSocketClient::jsonReceived, this, [](const QString &type, const QJsonObject &data) {
qDebug() << "Received JSON data: " << type << " " << data;
});
connect(websocketPushButton, &ElaPushButton::clicked, this, [this, client]() { // 设置服务端websocket地址
const QUrl url(websocketLineEdit->text().trimmed()); // 从LineEdit中获取服务端websocket地址
// 初始化客户端
if (client->setConfiguration(url)) {
ElaMessageBar::success(ElaMessageBarType::TopRight, "连接设置",
QString("服务器地址已设置为: %1").arg(url.toString()), 800.0, this);
return;
}
ElaMessageBar::warning(ElaMessageBarType::TopLeft, "连接设置",
QString("服务器地址存在问题"), 800.0, this);
});
connect(connectTestPushButton, &ElaPushButton::clicked, this, [this, client]() {
if (client->isConnected()) {
ElaMessageBar::success(ElaMessageBarType::TopRight, "连通测试",
"当前已连通", 800.0, this);
return;
}
client->connectToServer(); // 连接
// 使用定时器延迟检查连接状态
QTimer::singleShot(1000, this, [this, client]() {
if (!client->isConnected()) {
ElaMessageBar::warning(ElaMessageBarType::TopLeft, "连通测试",
"无法连接到服务器,请检查地址和服务器状态", 1500.0, this);
return;
}
ElaMessageBar::success(ElaMessageBarType::TopRight, "连通测试",
"连通测试成功", 800.0, this);
});
});
connect(connectPushButton, &ElaPushButton::clicked, this, [this, client]() {
if (client->isConnected()) {
ElaMessageBar::information(ElaMessageBarType::TopRight, "连接状态",
"已连接,无需重复连接", 800.0, this);
return;
}
const QString urlStr = websocketLineEdit->text().trimmed();
if (urlStr.isEmpty()) {
ElaMessageBar::warning(ElaMessageBarType::TopLeft, "连接",
"请先设置服务器地址", 800.0, this);
return;
}
// 确保使用正确的地址
client->setConfiguration(QUrl(urlStr));
client->connectToServer();
// 连接结果会在 connected/error 信号中处理
ElaMessageBar::information(ElaMessageBarType::TopRight, "连接",
"正在连接服务器...", 800.0, this);
});
connect(disconnectPushButton, &ElaPushButton::clicked, this, [this, client]() {
if (!client->isConnected()) {
ElaMessageBar::information(ElaMessageBarType::BottomRight, "断开连接",
"当前未连接", 800.0, this);
return;
}
client->disconnectFromServer();
ElaMessageBar::success(ElaMessageBarType::TopRight, "断开连接",
"已断开连接", 800.0, this);
});
connect(sendTestPushButton, &ElaPushButton::clicked, this, [this, netDO, client]() {
if (!client->isConnected()) {
ElaMessageBar::information(ElaMessageBarType::BottomRight, "断开连接",
"当前未连接", 800.0, this);
return;
}
// 创建数据包
QFile test_wav_file("Resources/TestFiles/test.wav");
if (!test_wav_file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open test.wav";
ElaMessageBar::warning(ElaMessageBarType::TopLeft, "发送测试",
"无法打开测试音频文件", 1500.0, this);
return;
}
QByteArray wavData = test_wav_file.readAll();
QString base64Str = QString::fromLatin1(wavData.toBase64());
AudioDataTransferObject packet;
packet.setData("Owner", "client")
.setData("isStream", true)
.setData("sequence", 42)
.setData("text", "Hello World")
.setData("data", base64Str); // 填入测试音频数据
netDO->sendPacket(packet);
ElaMessageBar::success(ElaMessageBarType::TopRight, "发送测试",
"已成功发送数据包", 1000.0, this);
});
}
+54
View File
@@ -0,0 +1,54 @@
//
// Created by Administrator on 2025/3/30.
//
#include "RenderPage.h"
#include <QHBoxLayout>
#include <QtWidgets>
#include "ElaComboBox.h"
#include "ElaMessageBar.h"
#include "ElaScrollPageArea.h"
#include "ElaText.h"
#include "GLCore.h"
#include "AppContext.h"
RenderPage::RenderPage(QWidget* parent)
: BasePage(parent)
{
// 预览窗口标题
setWindowTitle("RenderPage");
frameRateComboBox = new ElaComboBox(this);
QStringList frameRateComboList = GLCore::getFrameRateList();
frameRateComboBox->addItems(frameRateComboList);
ElaScrollPageArea* frameRateComboBoxArea = new ElaScrollPageArea(this);
QHBoxLayout* frameRateComboBoxLayout = new QHBoxLayout(frameRateComboBoxArea);
ElaText* frameRateComboBoxText = new ElaText("帧率设置", this);
frameRateComboBoxText->setTextPixelSize(15);
frameRateComboBoxLayout->addWidget(frameRateComboBoxText);
frameRateComboBoxLayout->addStretch();
frameRateComboBoxLayout->addWidget(frameRateComboBox);
frameRateComboBoxLayout->addSpacing(10);
connect(frameRateComboBox, &ElaComboBox::currentTextChanged, this, [this](const QString& text) {
AppContext::GetGLCore()->setFrameRate(GLCore::getFrameRateMap().value(text));
});
QWidget* centralWidget = new QWidget(this);
centralWidget->setWindowTitle("渲染设置");
QVBoxLayout* centerLayout = new QVBoxLayout(centralWidget);
centerLayout->addWidget(frameRateComboBoxArea);
centerLayout->addStretch();
centerLayout->setContentsMargins(0, 0, 0, 0);
addCentralWidget(centralWidget, true, true, 0);
}
RenderPage::~RenderPage()
{
}
+114
View File
@@ -0,0 +1,114 @@
//
// Created by Administrator on 2025/1/21.
//
#include <ElaTheme.h>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSvgRenderer>
#include <QPainter>
#include "Setting.h"
#include "socketmanager.h"
Setting::Setting(QWidget *parent)
: ElaWindow(parent)
{
// 设置窗口标题
setWindowTitle("设置");
// 设置窗口图标
setWindowIcon(QIcon("Resources/Pic/Airi/Airi_s.svg"));
// 初始化窗口
resize(1000, 740);
// 禁用窗口缩放按钮
setWindowButtonFlag(ElaAppBarType::MaximizeButtonHint, false); // 隐藏最大化按钮
setWindowButtonFlag(ElaAppBarType::MinimizeButtonHint, false); // 隐藏最小化按钮
// 移动窗口到屏幕中心
this->moveToCenter();
this->setWindowFlag(Qt::Tool); // 隐藏应用程序图标
this->setWindowFlag(Qt::WindowStaysOnTopHint); // 默认设置窗口始终在顶部
// 设置用户信息卡
this->setUserInfoCardTitle("Yosuga");
this->setUserInfoCardSubTitle("联系维度的桥梁!");
// 加载 SVG 图片
QSvgRenderer renderer(QString("Resources/Pic/Airi/Airi.svg"));
// 创建 QPixmap 并绘制 SVG
QPixmap pixmap(64, 64);
pixmap.fill(Qt::transparent); // 设置透明背景
QPainter painter(&pixmap);
renderer.render(&painter);
this->setUserInfoCardPixmap(pixmap);
// 初始化页面
initPages();
// 创建导航栏和内容区域
initNavigationBar();
// 创建上下文
initContent();
// 设置初始主题
eTheme->setThemeMode(ElaThemeType::Dark);
}
Setting::~Setting()
{
}
void Setting::initPages()
{
homePage = new HomePage(this);
networkPage = new NetWorkPage(this);
uiSetting = new UISetting(this);
audioPage = new AudioPage(this);
renderPage = new RenderPage(this);
modelPage = new ModelPage(this);
}
void Setting::initNavigationBar()
{
// 添加主页节点(顶级节点)
addPageNode("主页", homePage, ElaIconType::House);
// 添加模型商店节点
addPageNode("模型设置", modelPage, ElaIconType::Shop);
// 添加网络连接设置节点
addPageNode("连接设置", networkPage, ElaIconType::NetworkWired);
// 添加音频设置节点
addPageNode("音频设置", audioPage, ElaIconType::MusicNote);
// 添加渲染设置节点
addPageNode("渲染设置", renderPage, ElaIconType::ArrowsRotate);
QString uiSettingKey;
addFooterNode("UI设置", uiSetting, uiSettingKey, 0, ElaIconType::GearComplex);
}
void Setting::initContent()
{
connect(homePage, &HomePage::modelShopNavigation, this, [&](){
this->navigation(modelPage->property("ElaPageKey").toString());
});
connect(homePage, &HomePage::audioNavigation, this, [&](){
this->navigation(audioPage->property("ElaPageKey").toString());
});
}
void Setting::toggleTheme()
{
if (eTheme->getThemeMode() == ElaThemeType::Light) {
eTheme->setThemeMode(ElaThemeType::Dark);
} else {
eTheme->setThemeMode(ElaThemeType::Light);
}
}
+166
View File
@@ -0,0 +1,166 @@
//
// Created by Administrator on 2025/3/2.
//
#include "UISetting.h"
#include <QDebug>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "ElaApplication.h"
#include "ElaComboBox.h"
#include "ElaLog.h"
#include "ElaRadioButton.h"
#include "ElaScrollPageArea.h"
#include "ElaText.h"
#include "ElaTheme.h"
#include "ElaToggleSwitch.h"
#include "ElaWindow.h"
UISetting::UISetting(QWidget* parent)
: BasePage(parent)
{
// 预览窗口标题
ElaWindow* window = dynamic_cast<ElaWindow*>(parent);
setWindowTitle("Setting");
ElaText* themeText = new ElaText("主题设置", this);
themeText->setWordWrap(false);
themeText->setTextPixelSize(18);
_themeComboBox = new ElaComboBox(this);
_themeComboBox->addItem("日间模式");
_themeComboBox->addItem("夜间模式");
ElaScrollPageArea* themeSwitchArea = new ElaScrollPageArea(this);
QHBoxLayout* themeSwitchLayout = new QHBoxLayout(themeSwitchArea);
ElaText* themeSwitchText = new ElaText("主题切换", this);
themeSwitchText->setWordWrap(false);
themeSwitchText->setTextPixelSize(15);
themeSwitchLayout->addWidget(themeSwitchText);
themeSwitchLayout->addStretch();
themeSwitchLayout->addWidget(_themeComboBox);
connect(_themeComboBox, QOverload<int>::of(&ElaComboBox::currentIndexChanged), this, [=](int index) {
if (index == 0)
{
eTheme->setThemeMode(ElaThemeType::Light);
}
else
{
eTheme->setThemeMode(ElaThemeType::Dark);
}
});
connect(eTheme, &ElaTheme::themeModeChanged, this, [=, this](ElaThemeType::ThemeMode themeMode) {
_themeComboBox->blockSignals(true);
if (themeMode == ElaThemeType::Light)
{
_themeComboBox->setCurrentIndex(0);
}
else
{
_themeComboBox->setCurrentIndex(1);
}
_themeComboBox->blockSignals(false);
});
ElaText* helperText = new ElaText("应用程序设置", this);
helperText->setWordWrap(false);
helperText->setTextPixelSize(18);
_micaSwitchButton = new ElaToggleSwitch(this);
ElaScrollPageArea* micaSwitchArea = new ElaScrollPageArea(this);
QHBoxLayout* micaSwitchLayout = new QHBoxLayout(micaSwitchArea);
ElaText* micaSwitchText = new ElaText("启用云母效果", this);
micaSwitchText->setWordWrap(false);
micaSwitchText->setTextPixelSize(15);
micaSwitchLayout->addWidget(micaSwitchText);
micaSwitchLayout->addStretch();
micaSwitchLayout->addWidget(_micaSwitchButton);
connect(_micaSwitchButton, &ElaToggleSwitch::toggled, this, [=](bool checked) {
eApp->setIsEnableMica(checked);
});
_logSwitchButton = new ElaToggleSwitch(this);
ElaScrollPageArea* logSwitchArea = new ElaScrollPageArea(this);
QHBoxLayout* logSwitchLayout = new QHBoxLayout(logSwitchArea);
ElaText* logSwitchText = new ElaText("启用日志功能", this);
logSwitchText->setWordWrap(false);
logSwitchText->setTextPixelSize(15);
logSwitchLayout->addWidget(logSwitchText);
logSwitchLayout->addStretch();
logSwitchLayout->addWidget(_logSwitchButton);
connect(_logSwitchButton, &ElaToggleSwitch::toggled, this, [=](bool checked) {
ElaLog::getInstance()->initMessageLog(checked);
if (checked)
{
qDebug() << "日志已启用!";
}
else
{
qDebug() << "日志已关闭!";
}
});
_minimumButton = new ElaRadioButton("Minimum", this);
_compactButton = new ElaRadioButton("Compact", this);
_maximumButton = new ElaRadioButton("Maximum", this);
_autoButton = new ElaRadioButton("Auto", this);
_autoButton->setChecked(true);
ElaScrollPageArea* displayModeArea = new ElaScrollPageArea(this);
QHBoxLayout* displayModeLayout = new QHBoxLayout(displayModeArea);
ElaText* displayModeText = new ElaText("导航栏模式选择", this);
displayModeText->setWordWrap(false);
displayModeText->setTextPixelSize(15);
displayModeLayout->addWidget(displayModeText);
displayModeLayout->addStretch();
displayModeLayout->addWidget(_minimumButton);
displayModeLayout->addWidget(_compactButton);
displayModeLayout->addWidget(_maximumButton);
displayModeLayout->addWidget(_autoButton);
connect(_minimumButton, &ElaRadioButton::toggled, this, [=](bool checked) {
if (checked)
{
window->setNavigationBarDisplayMode(ElaNavigationType::Minimal);
}
});
connect(_compactButton, &ElaRadioButton::toggled, this, [=](bool checked) {
if (checked)
{
window->setNavigationBarDisplayMode(ElaNavigationType::Compact);
}
});
connect(_maximumButton, &ElaRadioButton::toggled, this, [=](bool checked) {
if (checked)
{
window->setNavigationBarDisplayMode(ElaNavigationType::Maximal);
}
});
connect(_autoButton, &ElaRadioButton::toggled, this, [=](bool checked) {
if (checked)
{
window->setNavigationBarDisplayMode(ElaNavigationType::Auto);
}
});
QWidget* centralWidget = new QWidget(this);
centralWidget->setWindowTitle("UI设置");
QVBoxLayout* centerLayout = new QVBoxLayout(centralWidget);
centerLayout->addSpacing(30);
centerLayout->addWidget(themeText);
centerLayout->addSpacing(10);
centerLayout->addWidget(themeSwitchArea);
centerLayout->addSpacing(15);
centerLayout->addWidget(helperText);
centerLayout->addSpacing(10);
centerLayout->addWidget(logSwitchArea);
centerLayout->addWidget(micaSwitchArea);
centerLayout->addWidget(displayModeArea);
centerLayout->addStretch();
centerLayout->setContentsMargins(0, 0, 0, 0);
addCentralWidget(centralWidget, true, true, 0);
}
UISetting::~UISetting()
{
}
+1
View File
@@ -0,0 +1 @@
设置界面,UI使用Ela UI