您的位置:首页 > 教育 > 培训 > 平面设计能干到老吗_正规网站制作公司是哪家_产品推广计划方案模板_免费发布信息网网站

平面设计能干到老吗_正规网站制作公司是哪家_产品推广计划方案模板_免费发布信息网网站

2025/4/18 10:39:06 来源:https://blog.csdn.net/2401_87117051/article/details/147233603  浏览:    关键词:平面设计能干到老吗_正规网站制作公司是哪家_产品推广计划方案模板_免费发布信息网网站
平面设计能干到老吗_正规网站制作公司是哪家_产品推广计划方案模板_免费发布信息网网站

文章目录

  • 前言
  • 一. 主页面框架
    • 1.创建菜单栏
      • (1)代码部分
      • (2)代码解析
      • (3)实现效果
    • 2.qss样式美化菜单栏
      • (1)代码解析
    • 3.qss样式美化后效果
    • 4.如何将qss样式添加?
      • (1)代码解析
  • 二. 加入注册页面的向导Wizard
    • 向导类Wizard框架思路图
      • (1)完成ProSetPage的ui部分
      • (2)如何进入注册界面向导类
      • (3)实现ProSetPage.cpp
        • 1.介绍isComplete
        • 2.重写iscomplete函数
        • 3.设置输入
        • 4.实现浏览按钮
      • (4)实现ConfirmPage.cpp
        • 1.ui部分
        • 2.重写done函数
  • 三. 主窗口进入注册页面


前言

提示:这里可以添加本文要记录的大概内容:
我们今天开始制作QT的第一个项目–电子相册,用到的都是之前发布的基础知识,我会在Github上同步我的进程,所有代码开源 CSDN中仅放部分代码!!!!!
本项目所使用的知识点
QListWidgetQTreeWidget双缓冲绘图信号槽动画效果绘图事件鼠标事件,qss等知识

最终可以实现一个可以有背景音乐,自动播放照片的电子相册
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一. 主页面框架

首先我们先把主页面框架做出来,首页的左侧是一个目录树,存放相册,右侧是显示照片的取余
这里我们直接用mainwindow.ui实现即可

在这里插入图片描述

1.创建菜单栏

我们在顶部先创建菜单栏

(1)代码部分

//创建菜单QMenu * menu_file=menuBar()->addMenu(tr("文件(&F)"));//创建设置菜单QMenu * menu_set=menuBar()->addMenu(tr("设置(&S)"));//新建QAction *act_creat_pro=new QAction(QIcon(":/photo/7a96a759b1e628c15d2992e8da2bebf.jpg"),tr("创建相册"),this);//快捷键act_creat_pro->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));menu_file->addAction(act_creat_pro);//打开QAction * act_open_pro=new QAction(QIcon(":/photo/e38198c26dc52b95a224af050b0951e.jpg"),tr("打开相册"),this);//快捷键act_open_pro->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));menu_file->addAction(act_open_pro);//设置背景音乐QAction* act_music=new QAction(QIcon(":/music/bandicam 2025-04-13 14-51-23-941.mp3"),tr("播放背景音乐"),this);act_music->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));menu_set->addAction(act_music);

(2)代码解析

menuBar是QT自带的,表示顶部状态栏

我们这创建了两个菜单,一个menu_file文件 一个menu_set设置
然后在两个菜单中分别加入两个动作,比如我现在有个文件菜单,我鼠标点击文件的时候,下方会显示创建相册和打开相册两个选项
并且还给每个按键加入了一个快捷键

(3)实现效果

在这里插入图片描述
在这里插入图片描述
我们发现此时都是白的,显然不好看,我们此处使用qss进行美化一下

2.qss样式美化菜单栏

MainWindow {background-color: rgb(46,47,48); /* 设置主窗口背景颜色 */
}/* 菜单栏颜色 */
QMenuBar {color: rgb(231,231,231); /* 文字颜色 */background-color: rgb(46,47,48); /* 背景颜色 */
}/* 菜单项颜色 */
QMenu {color: rgb(231,231,231); /* 文字颜色 */background: rgb(55,55,55); /* 背景颜色 */
}/* 选中菜单项时的样式 */
QMenuBar::item:selected {background-color: rgb(80,80,80); /* 选中时背景 */
}/* 选中菜单项时的样式 */
QMenu::item:selected {background-color: rgb(39,96,154 ); /* 选中时背景 */
}/*创建*/
QWizard{color:rgb(231,231,231);background-color:rgb(46,47,48);
}

(1)代码解析

1.设置装窗口样式

MainWindow {background-color: rgb(46,47,48); /* 设置主窗口背景颜色 */
}

将主窗口(mainwindow)的背景设置为深灰色
这里用了rgb 网上直接搜rgb颜色标记就行

2.设置菜单栏样式

QMenuBar {color: rgb(231,231,231); /* 文字颜色 */background-color: rgb(46,47,48); /* 背景颜色 */
}

设置菜单栏的背景颜色为深灰色,字体颜色为浅灰色

3.设置菜单项样式

QMenu {color: rgb(231,231,231); /* 文字颜色 */background: rgb(55,55,55); /* 背景颜色 */
}

将字体颜色设置为白色,背景为浅灰色

4.菜单栏中选中项样式

QMenuBar::item:selected {background-color: rgb(80,80,80); /* 选中时背景 */
}

当鼠标悬停或选中菜单栏的某个菜单项时,该项背景变为中灰色

5.菜单中的选中项样式

QMenu::item:selected {background-color: rgb(39,96,154); /* 选中时背景 */
}

当鼠标悬停或点击菜单内的选项时,该选项背景变为蓝色调,更醒目

3.qss样式美化后效果

在这里插入图片描述
在这里插入图片描述

4.如何将qss样式添加?

我们在main.cpp的开始显示窗口前 我们加入我们写好的qss样式表即可

QFile qss(":/style/style.qss");
if(qss.open(QFile::ReadOnly))//以只读的方式打开
{QString style=QLatin1String(qss.readAll());a.setStyleSheet(style);//设置样式表
}
else{//打开失败return 0;
}

(1)代码解析

QString style = QLatin1String(qss.readAll());

🌟 作用分解讲解

  1. qss.readAll()
    这部分表示:

    从打开的 qss 文件中读取全部内容(即整个 QSS 样式表)。

    返回类型是 QByteArray,即字节数组(不是 QString 字符串!)。

  2. QLatin1String(…)
    这是一个 Qt 提供的辅助类,用来将 Latin1 编码的字节数组(就是标准英文+常见西文字符编码)转换为一个 QString。

    它和 QString::fromUtf8(…) 类似,但只用于 Latin1 编码(不是中文或特殊符号)。

  3. 为什么不直接用 QString?
    因为 readAll() 返回的是 QByteArray,如果你直接赋值给 QString,可能会使用默认的编码方式,可能不是你想要的结果。
    使用 QLatin1String(…) 明确地告诉 Qt:“我读取的这个字节内容是 Latin1 编码的”,这样转换成 QString 更安全。

✅ 所以这一句完整理解是:
“从样式文件中读取所有内容(QByteArray),用 Latin1 编码方式转换为 QString 类 型,赋值给变量 style

二. 加入注册页面的向导Wizard

向导类Wizard框架思路图

在这里插入图片描述

我们进入软件 一开始是没有相册的,用户可以选中创建相册,然后选择相册名字和存放的相册路径
这里我们用到Qt中的设计师界面类 Wizard
在这里插入图片描述
然后此时有两个页面,我们再添加两个子类进来,重写这两个页面即可
第一个页面ProSetPage注册页面,第二个ConfirmPage完成页面
我们这里重写了Wizard中的两个子页面,那么Wizard.ui中的两个页面的类我们需要提升为我们加入的这两个类对象
在这里插入图片描述

(1)完成ProSetPage的ui部分

在这里插入图片描述
这里我们顶部输入名字和存放路径,路径的右侧有个浏览按钮,点击可以打开目录选择存放地址,然后下面有个tips 是一个label 如果用户输入错误的路径 我们会进行提示
两个弹簧的作用是为了让界面更美观

(2)如何进入注册界面向导类

当我们点击左上角文件的创建相册的时候,会进入这个注册页面,所以我们对创建相册这个按钮进行信号与槽的连通

//连接信号与槽  创建项目connect(act_creat_pro,&QAction::triggered,this,&MainWindow::SlotCreatePro);

然后我们直接在mainwindow.cpp主窗口中实现这个函数即可

void MainWindow::SlotCreatePro(bool)
{//qDebug()<<"slot create pro triggered"<<endl;Wizard wizard(this);//构造函数 父窗口设置为mainwindowwizard.setWindowTitle(tr("创建相册"));auto *page=wizard.page(0);//第一页page->setTitle(tr("相册名称与存放路径"));//连接信号与槽 把项目配置传回来todo//connect(&wizard,&Wizard::SigProSettings,// dynamic_cast<ProTree*>    (_protree),&ProTree::AddProTree);wizard.resize(600,400);//展示wizard.show();wizard.exec();//断开所有信号tododisconnect();}

中间注销掉的内容是后续我们确定完名字和路径点击完成的时候,要把这个回传回来,我们要放入左侧的目录树中,现在我们先不考虑这部分

此时我们完成到这一步,点击创建相册就会跳出这个窗口

在这里插入图片描述
这里我已经写好了qss样式和目录树,大家做到这与我不一样没关系

(3)实现ProSetPage.cpp

我们打开这个注册页面以后,肯定是准备让用户输入名字和路径了,我们为了防止用户在没有输入名字和路径的情况下就点击下一步,这里我们用注册域来限制用户必须输入名字与正确路径

registerField("proName*",ui->lineEdit);//这里*代表必填
registerField("proPath",ui->lineEdit_2);

此时用户在不断的输入名字和路径
我们要怎么判断用户是否输入的是正确的名字和路径呢
这里我们用到QWizard中的isComplete函数
在这里插入图片描述
我们重写这个虚函数即可

1.介绍isComplete

在这里插入图片描述
我们通过信号与槽 当用户输入这个名字与路径的时候,自动触发这个函数即可

connect(ui->lineEdit,&QLineEdit::textEdited,this,
&ProSetPage::completeChanged);//触发iscomplete函数connect(ui->lineEdit_2,&QLineEdit::textEdited,this,&ProSetPage::completeChanged);

这里的信号是completeChanged
🔔 当你发出 completeChanged() 信号时,Qt 会自动重新调用一次 isComplete() 函数,用于判断当前页是否“完成”

问题一:为什么此处用的是**&ProSetPage::completeChanged** 而不是
&QWizard::completeChanged
我们的ProSetPage是继承与QWizard 所以也能调用他的虚函数,但为什么这里不能用QWizard,因为它不是我当前对象(this)的直接成员函数

2.重写iscomplete函数

为了实现一些特定的判断 我们需要重新实现这个函数,因为并不是用户输入了名字和路径就能点击下一步,要输入正确的路径才行

//实现强制用户输入正确路径
bool ProSetPage::isComplete() const
{if(ui->lineEdit->text()==""||ui->lineEdit_2->text()==""){return false;//必须要输入}QDir dir(ui->lineEdit_2->text());//将文本当成路径 判断此路径是否存在if(!dir.exists()){ui->tips->setText("路径不存在!");return false;}//判断路径QString absFilePath=dir.absoluteFilePath(ui->lineEdit->text());//将第一个//text也拼接上来形成完整路径QDir dist_dir(absFilePath);if(dist_dir.exists()){ui->tips->setText("项目已存在!请更换路径或名字");return false;}ui->tips->setText("");//啥也不显示return QWizardPage::isComplete();//如果重写了基类的虚函数 后续还想再用其原本的功能 需要返回
}

✅ isComplete() 函数逻辑分解(用于向导页 ProSetPage)
🧩 步骤一:检查输入框是否为空
if (lineEdit->text() == “” || lineEdit_2->text() == “”) return false;
目的:
防止用户不填就跳转下一页,确保表单完整性
🗂️ 步骤二:验证路径是否存在
QDir dir(lineEdit_2->text());
if (!dir.exists()) {
tips->setText(“路径不存在!”);
return false;
}
目的:
及时阻止输入错误路径,避免后续操作失败。
📁 步骤三:判断项目目录是否已存在
QString absPath = dir.absoluteFilePath(lineEdit->text());
if (QDir(absPath).exists()) {
tips->setText(“项目已存在!请更换路径或名字”);
return false;
}
目的:
避免覆盖已有项目,确保创建路径唯一
如果路径不存在,我们就用absoluteFilePath将名字也拼接起来形成一个完整的路径
在这里插入图片描述

3.设置输入

我们打开注册这个界面的时候,我们的路径设置默认为当前路径
同时为输入设置光标 光标自动追到当前文本的最后

QString curPath=QDir::currentPath();ui->lineEdit_2->setText(curPath);//初始的默认路径为当前路径//设置光标ui->lineEdit_2->setCursorPosition(ui->lineEdit_2->text().size());

同时我们加入一个小图标,比如输入了一个很长的路径,发现错了,我们可以一键删除

//只要有输入 就能直接清除ui->lineEdit_2->setClearButtonEnabled(true);ui->lineEdit->setClearButtonEnabled(true);

在这里插入图片描述

4.实现浏览按钮

在这里插入图片描述
我们不仅可以让用户主动输入路径
也能点击目录 打开电脑下的目录直接选择
思路:
ui中选中此button点击转到槽
然后进行信号与槽的连接
实现一个槽函数即可

//浏览按钮
void ProSetPage::on_pushButton_clicked()
{QFileDialog file_dialog;file_dialog.setFileMode(QFileDialog::Directory);//设置为打开目录file_dialog.setWindowTitle(tr("选中存放的文件夹"));//默认打开路径QDir path=QDir::currentPath();file_dialog.setDirectory(path);//打开当前的文件file_dialog.setViewMode(QFileDialog::Detail);//以详细的信息方式显示QStringList list;//存放用户选中的if(file_dialog.exec()){list=file_dialog.selectedFiles();//用户选中的}if(list.length()<=0){return;}QString apath=list.at(0);//第一个ui->lineEdit_2->setText(apath);}

ProSetPage::on_pushButton_clicked() 浏览按钮点击事件详解
🧩 目的:
弹出文件夹选择对话框,让用户选择一个路径,并自动填入界面中的输入框lineEdit_2

✅ 第一步:创建并配置文件对话框

QFileDialog file_dialog;
file_dialog.setFileMode(QFileDialog::Directory);         // 设置为选择“目录”,不是文件
file_dialog.setWindowTitle(tr("选中存放的文件夹"));       // 设置窗口标题

🔎 解释:

QFileDialog 是 Qt 提供的文件对话框组件
setFileMode(QFileDialog::Directory) 表示:用户只能选择文件夹而不是文件
setWindowTitle 设置窗口的标题,tr() 是用于支持多语言

✅ 第二步:设置默认打开目录 + 视图样式

QDir path = QDir::currentPath();           // 获取当前工作目录
file_dialog.setDirectory(path);            // 设置默认打开路径为当前目录
file_dialog.setViewMode(QFileDialog::Detail); // 显示为详细信息模式

🔎 解释:
默认打开的是当前程序运行所在的路径(比如 D:\QtProject\Album\build);
Detail 视图让用户可以看到文件夹的详细信息(修改时间、大小等)

✅ 第三步:执行对话框并获取用户选择结果

QStringList list;//一个容器
if (file_dialog.exec()) {list = file_dialog.selectedFiles();    // 获取用户选中的文件夹列表
}

🔎 解释:
exec() 是以模态方式弹出文件选择窗口;
只有用户点“确定”后才会返回 true,然后用 selectedFiles() 拿到用户选择的路径;

✅ 第四步:判断是否选择了路径并更新输入框

if (list.length() <= 0) {return; // 用户没选就返回
}QString apath = list.at(0); // 只取第一个路径
ui->lineEdit_2->setText(apath); // 显示到界面上

🔎 解释:
如果用户什么都没选就关闭对话框,就什么都不做;
如果选择了,就把路径显示在输入框 lineEdit_2 上;

在这里插入图片描述
此时点击浏览按钮
就会弹出目录框 然后可以选择文件,选中后自动更新在path的输入框中

(4)实现ConfirmPage.cpp

1.ui部分

在这里插入图片描述
在这里插入图片描述
运行起来就是这样,那么我们后续点击完成,我们要把前面输入的名字 路径都返回给主窗口,给ProTree类,ProTree类用来在MainWindow左侧显示树形目录,这个之后介绍
那么怎么返回呢?
我们重写QWizard中的done这个虚函数就行
在这里插入图片描述

2.重写done函数
//实现完成按钮
void Wizard::done(int result)
{if(result==QDialog::Rejected){//如果结果是拒绝return QWizard::done(result);}QString name,path;ui->wizardPage1->GetProSettings(name,path);emit SigProSettings(name,path);//发出信号QWizard::done(result);//如果重写了基类的虚函数 //后续还想再用其原本的功能 需要再次调用
}

三. 主窗口进入注册页面

 //连接信号与槽  创建项目connect(act_creat_pro,&QAction::triggered,this,&MainWindow::SlotCreatePro);

如果点击创建相册,就会触发我们绑定的信号与槽,接下来我们实现槽函数就行

void MainWindow::SlotCreatePro(bool)
{//qDebug()<<"slot create pro triggered"<<endl;Wizard wizard(this);//构造函数 父窗口设置为mainwindowwizard.setWindowTitle(tr("创建相册"));auto *page=wizard.page(0);//第一页page->setTitle(tr("相册名称与存放路径"));//连接信号与槽 把项目配置传回来todoconnect(&wizard,&Wizard::SigProSettings,dynamic_cast<ProTree*>(_protree),&ProTree::AddProTree);wizard.resize(600,400);//展示wizard.show();wizard.exec();//断开所有信号tododisconnect();}

所有源码我放入Github中同步更新
Github源码地址点击此处
后续持续更新…

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com