#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QStackedWidget>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QMovie>
#include "childwidget.h"
#include "login.h"
#include "register.h"
#include"database.h"
#include "roleselection.h"
#include "levelselection.h"
#include"gamewidget.h"
#include"settingmusic.h"
// 在widget.h中添加
#include <QMediaPlayer>
#include <QMediaPlaylist>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
QStackedWidget *stackedWidget;
QWidget *mainPage;
childwidget *loginRegisterPage;
Login *pageLogin;
RegisterWidget *pageRegister;
// 主页面控件
QLabel *titleLabel;
QPushButton *btnRegisterLogin;
QPushButton *btnStartGame;
QPushButton *btnSettings;
QPushButton *btnLeaderboard;
QPushButton *btnExit;
QLabel *gifLabel;
QMovie *movie;
DatabaseManager*dbManager;
RoleSelection *roleSelectionPage; // 新增角色选择页
LevelSelection *levelSelectionPage;
int selectedRoleIndex;
QMediaPlayer *bgmPlayer; // 背景音乐播放器
settingmusic *settingsDialog;
// 背景音乐播放器
QMediaPlaylist *bgmPlaylist;
signals:
void loginSuccess();
private slots:
void onRegisterLoginClicked();
void onBackToMainPage();
void onGotoLogin();
void onGotoRegister();
void handleLogin(const QString &username, const QString &password);
void handleRegister(const QString &username, const QString &password, const QString &confirmPassword);
void handleRoleSelected(int index); // 处理角色选择
void handleLevelSelected(int index); // 处理关卡选择
// 在Widget构造函数中
};
#endif // WIDGET_H
#include "widget.h"
#include <QDebug>
#include <QMessageBox>
#include <QFont>
#include <QMediaPlaylist> // 添加这个头文件
Widget::Widget(QWidget *parent)
: QWidget(parent),
stackedWidget(nullptr),
mainPage(nullptr),
loginRegisterPage(nullptr),
pageLogin(nullptr),
pageRegister(nullptr),
titleLabel(nullptr),
btnRegisterLogin(nullptr),
btnStartGame(nullptr),
btnSettings(nullptr),
btnLeaderboard(nullptr),
btnExit(nullptr),
gifLabel(nullptr),
movie(nullptr),
bgmPlayer(nullptr),
bgmPlaylist(nullptr), // 添加这个成员变量的初始化
settingsDialog(nullptr),
dbManager(nullptr), // 添加数据库管理器的初始化
roleSelectionPage(nullptr),
levelSelectionPage(nullptr),
selectedRoleIndex(-1) // 初始化角色索引
{
setWindowTitle("哈基迷大探险");
resize(800, 700);
move(550, 50);
setWindowIcon(QIcon(":/picture/mimi1.png"));
// 1. 初始化堆栈窗体
stackedWidget = new QStackedWidget(this);
QVBoxLayout *mainContainerLayout = new QVBoxLayout(this);
mainContainerLayout->addWidget(stackedWidget);
mainContainerLayout->setContentsMargins(0, 0, 0, 0);
setLayout(mainContainerLayout);
// 2. 初始化主页面
mainPage = new QWidget();
QVBoxLayout *mainPageLayout = new QVBoxLayout(mainPage);
// ① 标题标签
titleLabel = new QLabel(mainPage);
titleLabel->setAlignment(Qt::AlignCenter);
titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
titleLabel->setMinimumSize(800, 200);
QPixmap originalPixmap(":/picture/title.png");
if (!originalPixmap.isNull()) {
QPixmap scaledPixmap = originalPixmap.scaled(
titleLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation
);
titleLabel->setPixmap(scaledPixmap);
} else {
titleLabel->setText("图片加载失败");
titleLabel->setStyleSheet("color: red");
}
mainPageLayout->addWidget(titleLabel);
mainPageLayout->addSpacing(40);
// ② 按钮网格
QGridLayout *gridLayout = new QGridLayout();
btnRegisterLogin = new QPushButton("注册/登录", mainPage);
btnStartGame = new QPushButton("开始游戏", mainPage);
btnSettings = new QPushButton("游戏设置", mainPage);
btnLeaderboard = new QPushButton("排行榜", mainPage);
btnExit = new QPushButton("退出游戏", mainPage);
QFont btnFont("Arial", 14);
QPushButton* btns[] = {btnRegisterLogin, btnStartGame, btnSettings, btnLeaderboard, btnExit};
for (auto btn : btns) {
btn->setFont(btnFont);
btn->setMinimumSize(200, 50);
btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
btn->setStyleSheet(
"QPushButton {"
" background-color: pink;"
" color: white;"
" border: 2px solid white;"
" font: bold 14px;"
" border-radius: 10px;"
"}"
"QPushButton:hover {"
" background-color: #ff88aa;"
"}"
"QPushButton:pressed {"
" background-color: white;"
" color: pink;"
"}"
);
}
gridLayout->addWidget(btnRegisterLogin, 0, 0);
gridLayout->addWidget(btnStartGame, 0, 1);
gridLayout->addWidget(btnSettings, 1, 0);
gridLayout->addWidget(btnLeaderboard, 1, 1);
gridLayout->addWidget(btnExit, 2, 0, 1, 2);
gridLayout->setSpacing(20);
gridLayout->setContentsMargins(50, 20, 50, 20);
mainPageLayout->addLayout(gridLayout);
// ③ 动图标签
gifLabel = new QLabel(mainPage);
gifLabel->setAlignment(Qt::AlignCenter);
movie = new QMovie(":/gif/mimi2.gif", QByteArray(), mainPage);
if (movie->isValid()) {
gifLabel->setMovie(movie);
movie->start();
gifLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
} else {
gifLabel->setText("动图加载失败");
gifLabel->setStyleSheet("color: red");
}
mainPageLayout->addWidget(gifLabel);
mainPageLayout->setContentsMargins(10, 10, 10, 10);
mainPageLayout->setSpacing(10);
mainPage->setLayout(mainPageLayout);
// 3. 初始化登录/注册相关页面
loginRegisterPage = new childwidget();
pageLogin = new Login();
pageRegister = new RegisterWidget();
// 初始化背景音乐播放器和播放列表
bgmPlayer = new QMediaPlayer(this);
bgmPlaylist = new QMediaPlaylist(this);
bgmPlaylist->setPlaybackMode(QMediaPlaylist::Loop); // 设置循环模式
bgmPlayer->setPlaylist(bgmPlaylist); // 将播放列表关联到播放器
// 添加背景音乐(根据实际文件路径修改)
bgmPlaylist->addMedia(QUrl("qrc:/music/bgm1.mp3"));
bgmPlayer->setVolume(70); // 设置初始音量
bgmPlayer->play(); // 开始播放
// 初始化设置窗口
settingsDialog = new settingmusic(bgmPlayer, this);
stackedWidget->addWidget(settingsDialog); // 添加到堆栈窗口
// 4. 添加页面到堆栈
stackedWidget->addWidget(mainPage);
stackedWidget->addWidget(loginRegisterPage);
stackedWidget->addWidget(pageLogin);
stackedWidget->addWidget(pageRegister);
stackedWidget->setCurrentWidget(mainPage); // 默认显示主页面
// 初始化数据库
dbManager = new DatabaseManager(this);
if (!dbManager->initDatabase()) {
QMessageBox::critical(this, "数据库错误", "无法初始化数据库,请检查应用权限");
}
roleSelectionPage = new RoleSelection();
stackedWidget->addWidget(roleSelectionPage); // 添加到堆栈
levelSelectionPage = new LevelSelection(); // 初始化关卡选择页
stackedWidget->addWidget(levelSelectionPage);
// 5. 连接信号与槽
connect(btnRegisterLogin, &QPushButton::clicked, this, &Widget::onRegisterLoginClicked);
connect(loginRegisterPage, &childwidget::backToMainPage, this, &Widget::onBackToMainPage);
connect(loginRegisterPage, &childwidget::gotoLoginPage, this, &Widget::onGotoLogin);
connect(loginRegisterPage, &childwidget::gotoRegisterPage, this, &Widget::onGotoRegister);
connect(pageLogin, &Login::loginRequested, this, &Widget::handleLogin);
connect(pageRegister, &RegisterWidget::registerRequested, this, &Widget::handleRegister);
connect(pageLogin, &Login::backToPrevious, this, &Widget::onRegisterLoginClicked);
connect(pageRegister, &RegisterWidget::backToPrevious, this, &Widget::onRegisterLoginClicked);
connect(btnExit, &QPushButton::clicked, this, &Widget::close);
connect(btnSettings, &QPushButton::clicked, this, [=]() {
stackedWidget->setCurrentWidget(settingsDialog);
settingsDialog->show();
});
// 连接设置窗口返回信号(修复了缺少的闭合括号)
connect(settingsDialog, &settingmusic::backToMainPage, this, [=]() {
stackedWidget->setCurrentWidget(mainPage);
});
// 连接登录成功后跳转角色选择页
connect(this, &Widget::loginSuccess, this, [=]() {
stackedWidget->setCurrentWidget(roleSelectionPage);
qDebug() << "登录成功,跳转至角色选择页";
});
// 连接角色选择页返回按钮(返回主页面)
connect(roleSelectionPage, &RoleSelection::backToPrevious, this, [=]() {
stackedWidget->setCurrentWidget(mainPage);
});
// 连接角色选择页的信号
connect(roleSelectionPage, &RoleSelection::roleConfirmed, this, [=](int index) {
QMessageBox::information(this, "选择成功",
QString("你选择了角色:%1").arg(roleSelectionPage->getRoleInfo(index).name));
stackedWidget->setCurrentWidget(levelSelectionPage);
});
connect(levelSelectionPage, &LevelSelection::backToRoleSelection, this, [=]() {
stackedWidget->setCurrentWidget(roleSelectionPage);
});
connect(levelSelectionPage, &LevelSelection::levelConfirmed, this, &Widget::handleLevelSelected);
connect(btnStartGame, &QPushButton::clicked, this, [=]() {
stackedWidget->setCurrentWidget(roleSelectionPage); // 跳转到角色选择
});
}
Widget::~Widget()
{
delete movie; // 手动释放动图
// 其他对象由Qt的父对象机制自动释放,无需手动delete
}
void Widget::onRegisterLoginClicked()
{
stackedWidget->setCurrentWidget(loginRegisterPage);
qDebug() << "切换到登录/注册选择页面";
}
void Widget::onBackToMainPage()
{
stackedWidget->setCurrentWidget(mainPage);
qDebug() << "切回主页面";
}
void Widget::onGotoLogin()
{
stackedWidget->setCurrentWidget(pageLogin);
qDebug() << "切换到登录页面";
}
void Widget::onGotoRegister()
{
stackedWidget->setCurrentWidget(pageRegister);
qDebug() << "切换到注册页面";
}
void Widget::handleLogin(const QString &username, const QString &password)
{
qDebug() << "登录请求 - 用户名:" << username << "密码:" << password;
// 检查数据库连接状态
if (!dbManager->m_db.isOpen() && !dbManager->m_db.open()) {
QMessageBox::critical(this, "登录失败", "数据库连接失败,请重试!");
return;
}
// 调用数据库管理器验证用户
if (dbManager->verifyUser(username, password)) {
QMessageBox::information(this, "登录成功", "登录成功,请选择角色!");
emit loginSuccess(); // 发送登录成功信号,触发跳转角色选择页
} else {
QMessageBox::warning(this, "登录失败", "用户名或密码不正确!");
}
}
void Widget::handleRegister(const QString &username, const QString &password, const QString &confirmPassword)
{
// 1. 检查密码一致性
if (password != confirmPassword) {
QMessageBox::warning(this, "注册失败", "两次输入的密码不一致!");
return;
}
// 2. 调用数据库管理器注册用户
if (dbManager->registerUser(username, password)) {
QMessageBox::information(this, "注册成功", "账号注册成功,可直接登录!");
stackedWidget->setCurrentWidget(mainPage); // 跳回主页面
} else {
// 注册失败:用户名已存在或数据库错误
if (dbManager->isUsernameExists(username)) {
QMessageBox::warning(this, "注册失败", "用户名已存在!");
} else {
QMessageBox::critical(this, "注册失败", "数据库操作错误,请稍后重试!");
}
}
}
void Widget::handleRoleSelected(int index)
{
selectedRoleIndex = index;
QMessageBox::information(this, "选择成功",
QString("你选择了角色:%1").arg(roleSelectionPage->getRoleInfo(index).name));
stackedWidget->setCurrentWidget(levelSelectionPage); // 跳转到关卡选择页
}
void Widget::handleLevelSelected(int index) {
const LevelInfo &level = levelSelectionPage->getLevelInfo(index);
// 创建游戏窗口并显示
GameWidget *gameWidget = new GameWidget();
// 可以在这里设置游戏关卡信息
gameWidget->show(); // 显示游戏窗口
this->hide(); // 隐藏主窗口
// 游戏结束后返回主窗口
connect(gameWidget, &GameWidget::destroyed, this, [=]() {
this->show();
delete gameWidget; // 确保释放内存
});
}
#ifndef SETTINGMUSIC_H
#define SETTINGMUSIC_H
#include <QDialog>
#include <QMediaPlayer>
#include <QSlider>
#include <QComboBox>
#include <QPushButton>
class settingmusic : public QDialog
{
Q_OBJECT
public:
explicit settingmusic(QMediaPlayer *player, QWidget *parent = nullptr);
signals:
void backToMainPage(); // 返回主界面信号
private slots:
void onVolumeChanged(int value);
void onMusicSelected(int index);
void onBackClicked();
private:
QMediaPlayer *musicPlayer; // 音乐播放器指针
QSlider *volumeSlider; // 音量滑块
QComboBox *musicSelector; // 音乐选择下拉框
QVector<QString> musicFiles; // 音乐文件路径列表
};
#endif // settingmusic_H
#include "settingmusic.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QDebug>
settingmusic::settingmusic(QMediaPlayer *player, QWidget *parent)
: QDialog(parent), musicPlayer(player)
{
setWindowTitle("游戏设置");
setFixedSize(400, 300);
setWindowIcon(QIcon(":/picture/mimi1.png"));
// 初始化音乐文件列表(根据实际资源修改)
musicFiles = {
":/music/unknowflowers.mp3"
};
// 音乐选择下拉框
QLabel *musicLabel = new QLabel("选择背景音乐:", this);
musicSelector = new QComboBox(this);
musicSelector->addItems({"轻松旋律"});
// 音量控制
QLabel *volumeLabel = new QLabel("音量:", this);
volumeSlider = new QSlider(Qt::Horizontal, this);
volumeSlider->setRange(0, 100);
volumeSlider->setValue(player->volume());
// 返回按钮
QPushButton *backBtn = new QPushButton("返回主界面", this);
backBtn->setMinimumHeight(40);
backBtn->setStyleSheet(
"QPushButton {"
" background-color: pink;"
" color: white;"
" border: 2px solid white;"
" font: bold 14px;"
" border-radius: 10px;"
"}"
"QPushButton:hover {"
" background-color: #ff88aa;"
"}"
);
// 布局设置
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addSpacing(30);
QHBoxLayout *musicLayout = new QHBoxLayout();
musicLayout->addWidget(musicLabel);
musicLayout->addWidget(musicSelector);
mainLayout->addLayout(musicLayout);
QHBoxLayout *volumeLayout = new QHBoxLayout();
volumeLayout->addWidget(volumeLabel);
volumeLayout->addWidget(volumeSlider);
mainLayout->addLayout(volumeLayout);
mainLayout->addStretch();
mainLayout->addWidget(backBtn, 0, Qt::AlignCenter);
mainLayout->setContentsMargins(50, 20, 50, 30);
mainLayout->setSpacing(20);
// 连接信号槽
connect(volumeSlider, &QSlider::valueChanged, this, &settingmusic::onVolumeChanged);
connect(musicSelector, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &settingmusic::onMusicSelected);
connect(backBtn, &QPushButton::clicked, this, &settingmusic::onBackClicked);
// 初始播放第一首音乐
if (!musicFiles.isEmpty()) {
musicPlayer->setMedia(QUrl(musicFiles.first()));
musicPlayer->setVolume(volumeSlider->value());
musicPlayer->play();
}
}
void settingmusic::onVolumeChanged(int value)
{
if (musicPlayer) {
musicPlayer->setVolume(value);
}
}
void settingmusic::onMusicSelected(int index)
{
if (musicPlayer && index >= 0 && index < musicFiles.size()) {
musicPlayer->stop();
musicPlayer->setMedia(QUrl(musicFiles[index]));
musicPlayer->play();
}
}
void settingmusic::onBackClicked()
{
emit backToMainPage();
hide(); // 隐藏设置窗口而不是关闭,保持音乐播放
}
其他功能可以使用音乐没有声音