#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QStackedWidget>
#include <QLabel> // 补充头文件(之前遗漏)
#include <QPushButton> // 补充头文件(之前遗漏)
#include <QMovie> // 补充头文件(之前遗漏)
#include "childwidget.h"
#include "login.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
QStackedWidget *stackedWidget;
QWidget *mainPage;
childwidget *loginPage;
// 主页面控件
QLabel *titleLabel;
QPushButton *btnRegisterLogin;
QPushButton *btnStartGame;
QPushButton *btnSettings;
QPushButton *btnLeaderboard;
QPushButton *btnExit;
QLabel *gifLabel;
QMovie *movie;
Login *pageLogin;
private slots:
void onRegisterLoginClicked();
void onBackToMainPage();
void onGotoLogin();
};
#endif // WIDGET_H
#include "widget.h"
#include <QLabel>
#include <QPushButton>
#include <QMovie>
#include <QPixmap>
#include <QFont>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent),
stackedWidget(nullptr),
mainPage(nullptr),
loginPage(nullptr),
titleLabel(nullptr),
btnRegisterLogin(nullptr),
btnStartGame(nullptr),
btnSettings(nullptr),
btnLeaderboard(nullptr),
btnExit(nullptr),
gifLabel(nullptr),
movie(nullptr)
{
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);
// 修正:setContentsMargins需要4个参数(左、上、右、下)
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);
// 修正:C++11列表初始化需要显式指定类型(QPushButton*)
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. 初始化登录页面
loginPage = new childwidget();
// 4. 添加页面到堆栈
stackedWidget->addWidget(mainPage);
stackedWidget->addWidget(loginPage);
stackedWidget->setCurrentWidget(mainPage); // 默认显示主页面
// 5. 连接信号与槽
connect(btnRegisterLogin, &QPushButton::clicked, this, &Widget::onRegisterLoginClicked);
connect(loginPage, &childwidget::backToMainPage, this, &Widget::onBackToMainPage);
connect(btnExit, &QPushButton::clicked, this, &Widget::close);
}
Widget::~Widget()
{
delete movie; // 手动释放动图(其他控件由父对象自动释放)
}
void Widget::onRegisterLoginClicked()
{
stackedWidget->setCurrentWidget(loginPage);
qDebug() << "切换到登录页面";
}
void Widget::onBackToMainPage()
{
stackedWidget->setCurrentWidget(mainPage);
qDebug() << "切回主页面";
}
#ifndef CHILDWIDGET_H
#define CHILDWIDGET_H
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QIcon>
#include <QSizePolicy>
#include <QFont>
#include <QMovie>
#include <QPixmap>
#include <QHBoxLayout>
#include <QDebug>
class childwidget : public QWidget
{
Q_OBJECT
public:
explicit childwidget(QWidget *parent = nullptr);
~childwidget();
signals:
// 必须声明返回主页面的信号(供Widget类连接)
void backToMainPage();
void gotoLoginPage();
public slots:
// 声明槽函数(之前遗漏)
void onCloseWindow();
private:
QMovie *movie; // 动图对象(成员变量,避免局部变量释放问题)
QPushButton *loginBtn; // 登录按钮(提升为成员变量,才能在构造函数外访问)
QPushButton *registerBtn; // 注册按钮(同上)
QPushButton *backBtn;
};
#endif // CHILDWIDGET_H
#include "childwidget.h"
// 构造函数
childwidget::childwidget(QWidget *parent)
: QWidget(parent), movie(nullptr), loginBtn(nullptr), registerBtn(nullptr)
{
setWindowTitle("哈基迷大探险 - 登录/注册");
setWindowIcon(QIcon(":/picture/mimi1.png"));
// 创建主垂直布局
QVBoxLayout *mainLayout = new QVBoxLayout(this);
// === 新增:返回按钮 ===
backBtn = new QPushButton("← 返回", this);
backBtn->setMinimumHeight(40);
backBtn->setMaximumHeight(40);
QFont btnFont = backBtn->font();
btnFont.setPointSize(11);
backBtn->setFont(btnFont);
backBtn->setStyleSheet("text-align: left; padding-left: 20px;");
// 将返回按钮加入主布局顶部
mainLayout->addWidget(backBtn);
mainLayout->addSpacing(10); // 添加一点间距
// 按钮水平布局(登录/注册)
QHBoxLayout *buttonLayout = new QHBoxLayout();
// 创建登录按钮
loginBtn = new QPushButton("登录", this);
loginBtn->setMinimumHeight(50);
loginBtn->setMaximumHeight(50);
loginBtn->setFont(btnFont);
loginBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
// 创建注册按钮
registerBtn = new QPushButton("注册", this);
registerBtn->setMinimumHeight(50);
registerBtn->setMaximumHeight(50);
registerBtn->setFont(btnFont);
registerBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
// 添加登录/注册按钮到水平布局
buttonLayout->addStretch(1);
buttonLayout->addWidget(loginBtn);
buttonLayout->addSpacing(30);
buttonLayout->addWidget(registerBtn);
buttonLayout->addStretch(1);
buttonLayout->setContentsMargins(30, 20, 30, 20);
// 动图标签(带白色背景)
QLabel *gifLabel = new QLabel(this);
gifLabel->setAlignment(Qt::AlignCenter);
gifLabel->setStyleSheet("background-color: white; border-radius: 10px;");
gifLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// 加载动图
movie = new QMovie(":/gif/mimi2.gif", QByteArray(), this);
if (movie->isValid()) {
gifLabel->setMovie(movie);
movie->start();
} else {
gifLabel->setText("动图加载失败");
gifLabel->setStyleSheet("background-color: white; color: red; font-size: 16px;");
qWarning() << "无法加载动图资源:/gif/mimi2.gif";
}
// 主布局设置
mainLayout->addLayout(buttonLayout);
mainLayout->addWidget(gifLabel, 1); // 可伸缩区域
mainLayout->setContentsMargins(10, 10, 10, 10);
mainLayout->setSpacing(15);
setLayout(mainLayout);
// === 信号连接 ===
connect(backBtn, &QPushButton::clicked, this, [=]() {
emit backToMainPage();
qDebug() << "返回按钮点击,跳转回主页面";
});
// 在 childwidget 构造函数中
connect(loginBtn, &QPushButton::clicked, this, [=]() {
emit gotoLoginPage();
qDebug() << "跳转到登录页面";
});
}
// 析构函数
childwidget::~childwidget()
{
if (movie) {
movie->stop();
delete movie;
movie = nullptr;
}
qDebug() << "childwidget destroyed";
}
#ifndef LOGIN_H
#define LOGIN_H
#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
class Login : public QWidget
{
Q_OBJECT
public:
explicit Login(QWidget *parent = nullptr);
signals:
// 提供信号:用户点击“返回”或“登录”
void backToPrevious(); // 返回上一页
void loginRequested(const QString &username, const QString &password); // 请求登录
private slots:
void onLoginClicked();
private:
QLineEdit *usernameEdit;
QLineEdit *passwordEdit;
QPushButton *loginBtn;
QPushButton *backBtn;
};
#endif // LOGIN_H
#include "login.h"
#include <QFormLayout>
#include <QHBoxLayout>
#include <QMessageBox>
Login::Login(QWidget *parent)
: QWidget(parent)
{
setWindowTitle("用户登录");
setFixedSize(300, 200);
QLabel *titleLabel = new QLabel("请登录", this);
titleLabel->setAlignment(Qt::AlignCenter);
QFont titleFont = titleLabel->font();
titleFont.setPointSize(14);
titleFont.setBold(true);
titleLabel->setFont(titleFont);
// 表单布局:账号密码
usernameEdit = new QLineEdit(this);
usernameEdit->setPlaceholderText("请输入用户名");
passwordEdit = new QLineEdit(this);
passwordEdit->setPlaceholderText("请输入密码");
passwordEdit->setEchoMode(QLineEdit::Password);
QFormLayout *formLayout = new QFormLayout;
formLayout->addRow("账号:", usernameEdit);
formLayout->addRow("密码:", passwordEdit);
// 按钮区域
loginBtn = new QPushButton("登录", this);
backBtn = new QPushButton("← 返回", this);
QHBoxLayout *btnLayout = new QHBoxLayout;
btnLayout->addWidget(backBtn);
btnLayout->addWidget(loginBtn);
// 主布局
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(titleLabel);
mainLayout->addSpacing(10);
mainLayout->addLayout(formLayout);
mainLayout->addSpacing(10);
mainLayout->addLayout(btnLayout);
mainLayout->addStretch();
setLayout(mainLayout);
// === 信号连接 ===
connect(loginBtn, &QPushButton::clicked, this, &Login::onLoginClicked);
connect(backBtn, &QPushButton::clicked, this, &Login::backToPrevious);
}
void Login::onLoginClicked()
{
QString username = usernameEdit->text().trimmed();
QString password = passwordEdit->text();
if (username.isEmpty()) {
QMessageBox::warning(this, "输入错误", "用户名不能为空!");
return;
}
if (password.length() < 6) {
QMessageBox::warning(this, "输入错误", "密码不能少于6位!");
return;
}
// 发出登录请求信号(可在 MainWindow 中处理验证)
emit loginRequested(username, password);
}
#ifndef REGISTER_H
#define REGISTER_H
#include <QWidget>
class register : public QWidget
{
Q_OBJECT
public:
explicit register(QWidget *parent = nullptr);
signals:
public slots:
};
#endif // REGISTER_H
#include "register.h"
register::register(QWidget *parent) : QWidget(parent)
{
}