Qt快速入门到熟练(电子相册项目(一))

        经过一段时间的学习,相信大家对QT的基本用法都有所了解,从这篇文章开始,我准备记录一下电子相册的项目的一个学习过程。

实现项目创建功能

        对于这个电子相册的项目,我并没有在一开始就把所有可能用到的功能模块去事无巨细的考虑周全,我采用的方式是写到哪里我们在此基础上在添加功能,这样的好处是可以简化思维逻辑构建的复杂程度,避免在项目初期就由于考虑过多内容逻辑混乱无从下手。

新建mainwindow的项目

        不管我们做什么项目,首先需要一个主界面,在主界面的基础上我们进行功能的改进和模块的添加。这里我新建一个mainwindow的项目,不使用之前我们常用的Widget是因为mainwindow的项目自带菜单栏,可以更快构建我们项目的主要功能。

添加菜单栏

        新建mainwindow项目完成后,我们就需要在菜单栏中添加我们需要用到的菜单,刚开始我们只需要文件和设置两个选项,在文件列表里面需要添加创建文件和打开文件,设置里面可以暂时不用添加,也可以添加一个背景音乐的选项作为临时凑数。

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);
//    ui->dockWidget->header()->hide();//创建菜单栏QMenu * menu_file = menuBar()->addMenu(tr("文件(&F)"));//创建项目动作QAction * act_create_pro = new QAction(QIcon(":/icon/createpro.png"), tr("创建项目"),this);act_create_pro->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));menu_file->addAction(act_create_pro);//打开项目动作QAction * act_open_pro = new QAction(QIcon(":/icon/openpro.png"), tr("打开项目"),this);act_open_pro->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));menu_file->addAction(act_open_pro);//创建设置菜单QMenu * menu_set = menuBar()->addMenu(tr("设置(&S)"));//设置背景音乐动作QAction * act_music = new QAction(QIcon(":/icon/music.png"), tr("背景音乐"),this);act_music->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M));menu_set->addAction(act_music);}

为主窗口添加QDockWidget

        为实现一个电子相册,我们需要一个能够显示文件和图片列表的一个窗口,这里我选择使用一个QDockWidget来作为显示文件列表的窗口,然后在QDockWidget中添加treeWidgetlabel作为显示列表的容器,然后把QDockWidget设置为NoDockWidgetArea,来限制其可停靠的区域,并且取消其最大化和关闭窗口选项。

添加QSS

        观察上方运行结果,可以发现我的界面和你们的可能有些不同,我的界面是经过界面美化过的。在QT中界面美化一般都是通过编写QSS文件,然后在主函数调用的方式来完成界面美化,现在我们就来编写一下暂时所要用到的QSS条目:

创建一个QSS文件将其命名为style.qss

/*mainwindow 样式*/
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-color:rgb(55,55,55);
}/* 菜单栏选中条目时 */
QMenuBar::item:selected {background-color:rgb(80,80,80);
}/*菜单选中条目*/
QMenu::item:selected {background-color:rgb(39,96,154);
}QDockWidget:title
{background-color:rgb(46,47,48);
}/*为QDockWidget添加边框*/
QDockWidget>QWidget
{border-color: #9F9F9F;border-style: solid;border-width: 1px 1px 1px 1px;padding-right: 10px;
}QDockWidget QLabel#label {color: rgb(231,231,231);border-color: #9F9F9F;border-style: dotted;border-width: 0 0 1px 0;padding-bottom: 10px;margin-bottom: 5px;
}QTreeView {color:rgb(231,231,231);background-color:rgb(46,47,48);border: 0px;
}QWizard {color:rgb(231,231,231);background-color:rgb(46,47,48);
}QWizard QLabel#tips {color: red;
}

        那么我们创建的qss文件该存放到哪里呢,不错qss文件和其他资源文件一样,都可以存放到我们的资源文件里面。所以我们创建一个QT资源文件,把创建好的qss文件添加进去。有些读者可能注意到了我在添加菜单栏的时候同时为它们设置了QIcon,这里面所用到的图片我一样是添加到了资源文件里面,只不过在之前没有明说,你们也可以选择自己喜欢的QIcon图片。

添加完成后现在我的资源文件的目录如下:

        上面我们说过,qss需要在主函数调用才能真正配置成功,所以下面我们就需要在主函数里面把qss里面的格式给它配置到我们的Qt程序中:

int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;QFile qss(":/style/style.qss");if(qss.open(QFile::ReadOnly)){qDebug("open qss success");QString style = QLatin1String(qss.readAll());a.setStyleSheet(style);qss.close();}else{qDebug("Open failed");}w.show();return a.exec();
}

 在mainwindow.cpp中添加槽函数

        添加两个connect,在菜单文件中有两个QAction,针对这个两个QAction分别编写连接创建项目槽函数和连接打开项目的槽函数。

    //连接创建项目槽函数wizard = new Wizard(this);connect(act_create_pro, &QAction::triggered, wizard, &Wizard::SlotCreatePro);//连接打开项目的槽函数connect(act_open_pro, &QAction::triggered, this, &MainWindow::SlotOpenPro);//connect(this, &MainWindow::SigOpenPro, pro_tree_widget, &ProTreeWidget::SlotOpenPro);

创建向导类

点击创建项目,需要弹出一个向导界面,对创建项目进行配置引导。

所以我们点击添加新文件,选择Qt设计师界面类,选择界面模板为QWizard

        Wizard类ui自带两个QWizardPage,所以我们完全可以不用单独新建不同的QWizardPage类,但是对于Wizard类没有办法直接调用QWizardPage中registerField函数注册名为 "proPath" 的字段,并将其与 ui->LineEdit 组件相关联。所以对于不需要使用QWizardPage中函数的页面,无需新建QWizardPage类。

        我们在向导首页面需要设置项目的name和path,所以我们还要新建一个QWizardPage设计类,将其命名为WizardPage1。设置界面为如图所示

        在Wizard类的wizard.ui里面对wizardPage1提升为我们刚才新建的WizardPage1类,这样我们在wizardPage1.ui里面的设计都会继承到Wizard类的wizard.ui里面。

添加创建项目槽函数

        之前在mainwindow里面我们连接了一个向导类的槽函数SlotCreatePro,这里我们着手将其实现出来,

void Wizard::SlotCreatePro(bool){qDebug() << "slot create pro triggered" << endl;
//    Wizard wizard(this);this->setWindowTitle(tr("创建项目"));
//   auto *page = this->page(0);ui->wizardPage1->setTitle(tr("设置项目配置"));QVBoxLayout *layout = new QVBoxLayout(ui->wizardPage1);layout->setContentsMargins(10, 200, 10, 10);layout->addWidget(ui->wizardPage1);//连接信号和槽//connect(&wizard, &Wizard::SigProSettings, dynamic_cast<ProTree*>(_protree),&ProTree::AddProToTree);this->show();this->exec();
//    disconnect(&wizard);
}

        现在我们已经初步实现了向导界面的框架,之后我们只需要编写首页面的处理逻辑,本次的文章就完满完成。

进行WizardPage1逻辑编写

        将两个lineEdit注册为wizard的field,保证两个lineEdit是空的时候无法点击下一步,将QLineEdit的textEdited信号和WizardPage1的completeChanged信号连接起来,这样在lineEdit编辑的时候就会发送textEdited信号,进而触发WizardPage1发送completeChanged信号。
setClearButtonEnabled设置为true可以在lineEdit输入数据后显示清除按钮,直接清除已录入的字符。
        completeChanged信号是从WizardPage1的基类QWizardPage类继承而来的。completeChanged信号发出后会触发QWizardPage类的isComplete函数。

WizardPage1::WizardPage1(QWidget *parent) :QWizardPage(parent),ui(new Ui::WizardPage1)
{ui->setupUi(this);registerField("proPath", ui->lineEdit_2);registerField("proName", ui->lineEdit);connect(ui->lineEdit, &QLineEdit::textEdited, this, &WizardPage1::completeChanged);connect(ui->lineEdit_2, &QLineEdit::textEdited, this, &WizardPage1::completeChanged);QString curPath = QDir::currentPath();ui->lineEdit_2->setText(curPath);ui->lineEdit_2->setCursorPosition( ui->lineEdit_2->text().size());ui->lineEdit->setClearButtonEnabled(true);ui->lineEdit_2->setClearButtonEnabled(true);
}

为了实现特定的判断,我们重写isComplete函数。这样我们就能判断文件夹是否合理以及是否已经有项目路径了。
可以根据不满足的条件设置tips提示用户。

bool WizardPage1::isComplete() const
{if(ui->lineEdit->text() == "" || ui->lineEdit_2->text() == ""){return false;}//判断是否文件夹是否合理QDir dir(ui->lineEdit_2->text());if(!dir.exists()){//qDebug()<<"file path is not exists" << endl;ui->tips->setText("project path is not exists");return false;}//判断路径是否存在QString absFilePath = dir.absoluteFilePath(ui->lineEdit->text());
//    qDebug() << "absFilePath is " << absFilePath;QDir dist_dir(absFilePath);if(dist_dir.exists()){ui->tips->setText("project has exists, change path or name!");return false;}ui->tips->setText("");return QWizardPage::isComplete();
}

为浏览按钮添加点击后选择文件夹操作,在wizardPage1.ui文件里右键点击浏览按钮,选择转到槽,QT会为我们生成槽函数

void WizardPage1::on_pushButton_clicked()
{QFileDialog file_dialog;file_dialog.setFileMode(QFileDialog::Directory);file_dialog.setWindowTitle("选择导入的文件夹");auto path = QDir::currentPath();file_dialog.setDirectory(path);file_dialog.setViewMode(QFileDialog::Detail);QStringList fileNames;if (file_dialog.exec()){fileNames = file_dialog.selectedFiles();}if(fileNames.length() <= 0){return;}QString import_path = fileNames.at(0);qDebug() << "import_path is " << import_path << endl;ui->lineEdit_2->setText(import_path);
}

        在wizardPage1页面点击下一步会跳转到下一页。这一页没什么代码,在ui文件里添加提示即可,然后点击完成按钮完成创建。在完成时我们可以重写QWidzard的done函数。
将页面设置的项目名称和路径传递给ProTree类,ProTree类用来在MainWindow左侧显示树形目录,这个之后介绍。

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);
}

        这里面我们定义了一个GetProSettings函数去获取从lineEdit里面得到的name和path信息。然后设计一个信号把name和path信息给发出去。

void WizardPage1::GetProSettings(QString &name, QString &path)
{name = ui->lineEdit->text();path = ui->lineEdit_2->text();
}

        到此为止我们创建项目有关的内容已经基本完成,下一节我们将会去实现关于把项目文件列表在treeView里面显示出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/13617.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过域名接口申请免费的ssl多域名证书

来此加密已顺利接入阿里云的域名接口&#xff0c;用户只需一键调用&#xff0c;便可轻松完成域名验证&#xff0c;从而更高效地申请证书。接下来&#xff0c;让我们详细解读一下整个操作过程。 来此加密官网 免费申请SSL证书 免费SSL多域名证书&#xff0c;泛域名证书。 首先&a…

Intellij IDEA创建springboot项目

1、点击 Create New Project 2、选择 Spring Initializr —> 点击下一步 3、备注&#xff1a; Artifact为项目名称 group为项目组名 language设置为java packaging为打包方式 3、选择相应的依赖&#xff0c;也可以自己导入&#xff0c;在Developer Tools 、Web 、SQL 中选…

开箱即用,简单上手体验LobeChat搭建私人ChatGPT

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【LeetCode算法】第69题:x的平方根

目录 一、题目描述 二、初次解答 三、官方解法 四、总结 一、题目描述 二、初次解答 1. 思路&#xff1a;第一次想到的是让i从1开始遍历&#xff0c;看i*ix是否成立&#xff0c;但是这样就会导致i*i超出了int的范围&#xff0c;无法正常求解。第二次&#xff0c;想着比较x/…

H800基础能力测试

H800基础能力测试 参考链接A100、A800、H100、H800差异H100详细规格H100 TensorCore FP16 理论算力计算公式锁频安装依赖pytorch FP16算力测试cublas FP16算力测试运行cuda-samples 本文记录了H800基础测试步骤及测试结果 参考链接 NVIDIA H100 Tensor Core GPU Architecture…

【传知代码】从零开始搭建图像去雾神经网络-论文复现

文章目录 概述原理介绍网络结构 核心逻辑迁移学习子网数据拟合子网 环境配置训练本次复现代码所用数据集测试本次复现代码所用的评价指标 结果展示在O-Haze数据集上的结果在I-Haze数据集上的结果 小结 本文涉及的源码可从从零开始搭建图像去雾神经网络该文章下方附件获取 本文复…

tomcat--应用部署

tomcat根目录结构 Tomcat中默认网站根目录是/usr/local/apache-tomcat-8.5.100/webapps/在Tomcat的webapps目录中&#xff0c;有个非常特殊的目录ROOT&#xff0c;它就是网站默认根目录。将eshop解压后的文件放到这个/usr/local/apache-tomcat-8.5.100/webapps/ROOT中。bbs解压…

Git简单理解

Git 概述 Git 是一个免费的开源的&#xff0c;分布式版本控制系统&#xff0c;可以快速高效的处理从小型到大型的各种项目 Git占地面积小&#xff0c;性能极快&#xff0c;具有廉价的本地库&#xff0c;方便的暂存区和多个工作流分支等特性 版本控制 版本控制是一种记录文件…

低耦合双写一致性方案-使用canal+MQ

需求&#xff1a;继上一篇使用xxljob实现数据的全量同步到es后&#xff0c;当数据库中新增、删除、修改数据时&#xff0c;应该对es中的对应索引库实现增量同步。 本文介绍了2种双写一致性方案&#xff0c;对其中使用MQ的方案进行了实现。 1. 方案设计 1.1 数据一致性问题分析…

2024.5.21欧洲商会网络安全大会(上海)

本次安策将将参加超越 2024 年网络安全大会&#xff1a;驾驭数字前沿大会(上海)&#xff0c;2024年5月21日&#xff0c;期待和欢迎新老朋友在大会上会面和交流。 时间 2024-05-21 |14:00 - 16:30 场地&#xff1a; 上海瑞士大酒店 地址&#xff1a; 3rd Floor&#xff0c; Davo…

iOS 17.5 release notes

文章目录 iOS 17.5 更新恢复了多年前删除的一些图片新增彩虹壁纸欧盟用户可直接从网站下载应用新增了追踪通知改进 Apple News图书应用"阅读目标"设计更新颜色匹配的播客小部件Web浏览器安全权限的访问下一代“Beats Pill”扬声器在iOS 17.5代码中得到确认店内Vision…

【C++】 单例设计模式的讲解

前言 在我们的学习中不免会遇到一些要设计一些特殊的类&#xff0c;要求这些类只能在内存中特定的位置创建对象&#xff0c;这就需要我们对类进行一些特殊的处理&#xff0c;那我们该如何解决呢&#xff1f; 目录 1. 特殊类的设计1.1 设计一个类&#xff0c;不能被拷贝&#xf…

Android Studio 与 Gradle 及插件版本兼容性

Android Studio 开始新项目时&#xff0c;会自动创建其中部分文件&#xff0c;并为其填充合理的默认值。 项目文件结构布局&#xff1a; 一、Android Gradle 及插件作用&#xff1a; Android Studio 构建系统以 Gradle 为基础&#xff0c;并且 Android Gradle 插件 (AGP) 添加…

代码随想录阅读笔记-动态规划【不同路径 II】

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为“Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为“Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到右…

全球视频会议软件巨头Zoom,率先引入后量子端到端加密

5月21日&#xff0c;Zoom Video Communications公司宣布&#xff0c;后量子端到端加密&#xff08;E2EE&#xff09;现已面向全球推出&#xff0c;适用于Zoom Workplace。目前&#xff0c;Zoom已将该功能加入Zoom Meetings&#xff0c;稍后将扩展至Zoom Phone和Zoom Rooms。 图…

视频批量裁剪助手:一键式高效缩小视频尺寸,极速提升工作效率的必备神器!

视频已经成为我们日常生活和工作中不可或缺的一部分。无论是个人vlog、企业宣传片&#xff0c;还是教学视频、广告素材&#xff0c;视频都承载着大量的信息和情感。然而&#xff0c;很多时候&#xff0c;我们手中的视频尺寸并不符合我们的需求&#xff0c;这时&#xff0c;一款…

He3DB MySQL计算下推优化设计

前言 计算下推是数据库优化器优化查询性能的一种常见手段&#xff0c;早期的数据库系统提及的计算下推一般是指谓词下推&#xff0c;其 理论源自关系代数理论。 2000 年以后&#xff0c;随着 Oracle RAC 的盛行以及一众开源分布式数据库的崛起&#xff0c;存算分离的概 念逐步…

k8s 声明式资源管理

一、资源配置清单的管理 1.1 查看资源配置清单 声明式管理方法&#xff1a; 1.适合于对资源的修改操作 2.声明式资源管理方法依赖于资源配置清单文件对资源进行管理 资源配置清单文件有两种格式&#xff1a;yaml&#xff08;人性化&#xff0c;易读&#xff09;&#xff0c;j…

Flink 调度源码分析4:Physical Slot 分配过程

Flink 调度源码分析1&#xff1a;拓扑图创建与提交过程 Flink 调度源码分析2&#xff1a;调度过程 Flink 调度源码分析3&#xff1a;Shared Slot 分配策略 Flink 调度源码分析4&#xff1a;Physical Slot 分配过程 1 整体过程 在 SlotSharingExecutionSlotAllocator.allocate…

【EXCEL_VBA_实战】两组数据比对是否一致(字符串数组)

工作背景&#xff1a;比对两组数据是否一致&#xff08;位置非一一对应&#xff09; 思路构建&#xff1a;两组数据转换为两组字符串数组&#xff0c;比对所包含元素是否相同 问题点&#xff1a;A数组的第一个元素不一定与B数组的第一个元素对应&#xff0c;此时无法通过公式…