Qt实现一个电子相册

news2024/10/7 6:33:46

一、要实现的功能

  1. 在窗口中可以显示图片,并且能够通过两个按钮进行图片的前进和后退的顺序切换。
  2. 有一个按钮,通过这个按钮可以从所存图片资源中随机选取一个图片进行展示
  3. 通过按钮可以控制图片自动轮播顺序切换的开始与停止,
  4. 显示当前系统的时间。

二、实现思路

可以使用标签组件QLabel来显示图片,需要主要的是图片的大小与Qlabel之间大小关系。图片显示载体的问题解决后,再思考图片资源的读取途径,由于图片的前后切换需要顺序的遍历图片资源,所以我们可以用顺序容器QList 来创建一个列表对象,将所需的图片的路径保存在该列表中,这样我们在找图片时就可以通过 QList 列表的下表的加加减减来进行顺序选择对应图片的路径,同时也可以随机产生一个列表下表随机选择一张图片。然后再考虑按钮点击和图片切换功能之间的绑定关系,很明显可以使用信号与槽来实现,自定义槽函数,槽函数中实现图片切换的对应功能,按钮触发自带的clicked信号,按钮信号与自定义槽函数绑定,这样就可以实现点击按钮切换图片的效果了。

对于图片的自动切换,可以通过定时器QTimer 来指定图片自动轮播的间隔时间,时间间隔一到就触发对应的图片切换槽函数。

显示当前的系统时间的话,可以通过QDateTime获取当前系统的时间,然后使用QLCDNumber组件来显示。

三、实现的基本步骤

由于界面不太复杂,没有多重界面之间的切换,所以再新建项目工程文件时,下面的这一界面中的基类选则可以为QDialog,同时为了方便界面各个组件的设计,可以勾选上下面的“创建界面”选项。
在这里插入图片描述
界面布局:
在这里插入图片描述
对于图片资源,为了较好的显示效果,我都将图片裁剪成了相同的大小,图片的添加过程如下:

  1. 找到图片资源,格式要求为jpg、png、bmp,不要选择过大的图片(分辨率、文件大小)。
  2. 更改图片名称,名称建议为全英文、下划线和数字组合,且英文全小写,数字不能开头。
  3. 把图片放置到工作目录中。
  4. 在Qt Creator中选中项目名称,鼠标右键,点击“添加新文件”。
  5. 按照下图所示进行操作。在这里插入图片描述
  6. 在弹出的窗口中设置资源文件名称在这里插入图片描述
  7. 在项目管理界面,直接点击完成。可以看到项目中多了一个.qrc的资源文件。在这里插入图片描述
  8. 选中qrc文件,点击“添加前缀”。在这里插入图片描述
  9. 再次点击添加里面的添加文件在这里插入图片描述
    在弹出的对话框窗口中选中要添加的图片文件。添加成功后会在qrc文件中显示出来。
  10. 点击Qt Creater左下角的锤子🔨,对项目进行构建一下,其实就是编译一下,这样资源文件就可以被Designer找到,随后就可以在 Designer 中设置图片了。

创建QList对象,存放图片路径:
在这里插入图片描述
在这里插入图片描述
图片路径存放在imglist列表中,可以通过imglist.at(i)来取元素,为了在其他成员函数中都能够获取当前显示的是哪张图片,需要在Dialog类中设置一个用于保存正在显示的图片在imglist列表中的下标,如下:
在这里插入图片描述
定义点击按钮切换图片的槽函数声名:
在这里插入图片描述
然后编写显示上一张的按钮、显示下一张的按钮随机显示图片的按钮对应的槽函数:👇
在这里插入图片描述
其中要注意的是随机数的产生方法,先使用QDateTime类下的currentMSecsSinceEpoch()成员函数返回一个1970-1-1 00:00:00到到现在的毫秒数的一个时间,然后使用这个时间作为生成随机数的种子,调用qrand()产生随机数。

图片的轮播使用的是QTimer定时器实现,通过其成员函数start()开启一个定时器👇
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定时时间到后触发timeout()信号,故也用信号槽来实现,定时时间到后的槽函数就是切换下一张图片,和上面的代码类似👇
在这里插入图片描述
在这里插入图片描述

对于图片轮播开始或结束按钮的槽函数👇
在这里插入图片描述
在这里插入图片描述

对于时间显示,也要设置一个定时器来实现,可以定时一秒,定时时间一到就释放timeout()的信号,同时自定义一个槽函数来更新QLCDNumber上面的时间显示,对应代码如下:👇
在这里插入图片描述
在这里插入图片描述

三、运行效果图

在这里插入图片描述

四、项目代码

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QDebug>
#include <QString>
#include <QDateTime>
#include <QList>
#include <QTimer>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    int imgnum; // 图片序号
    bool flag = true; // 轮播按钮状态标志
    QPixmap *pix;   // 建立QPixmap对象
    QTimer *timer; //设置定时器
    QTimer *flashtimer; // 1秒刷新
    QList<QString> imglist; // 图片路径列表
private slots:
    void preImgBtnSlot(); // 前一张图片槽函数
    void nextImgBtnSlot(); // 后一张图片槽函数
    void randomImgBtnSlot(); // 随机图片槽函数
    void carouseBtnSlot(); // 轮播开始or暂停按钮槽函数
    void imgCarouselSlot(); //图片自动轮播槽函数
    void updateTimeSlot();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog),imgnum(0)
{
    ui->setupUi(this);

    pix = new QPixmap;
    timer = new QTimer;
    flashtimer = new QTimer;
    timer->start(2000); // 设置2秒定时
    flashtimer->start(1000);

    QString imgpath1 = ":/new/prefix1/image/img1.jpg";
    QString imgpath2 = ":/new/prefix1/image/img2.jpg";
    QString imgpath3 = ":/new/prefix1/image/img3.jpg";
    QString imgpath4 = ":/new/prefix1/image/img4.jpg";
    QString imgpath5 = ":/new/prefix1/image/img5.jpg";

    imglist <<imgpath1 <<imgpath2 <<imgpath3 <<imgpath4 <<imgpath5;

    connect(ui->prePushBtn,SIGNAL(clicked()),this,SLOT(preImgBtnSlot()));
    connect(ui->nextPushBtn,SIGNAL(clicked()),this,SLOT(nextImgBtnSlot()));
    connect(ui->randomPushBtn,SIGNAL(clicked()),this,SLOT(randomImgBtnSlot()));
    connect(ui->carousePushBtn,SIGNAL(clicked()),this,SLOT(carouseBtnSlot()));
    connect(ui->pushButtonClose,SIGNAL(clicked()),this,SLOT(close())); // 关闭窗口
    connect(flashtimer,SIGNAL(timeout()),this,SLOT(updateTimeSlot()));

    // 定时器信号槽
    connect(timer,SIGNAL(timeout()),this,SLOT(imgCarouselSlot()));

    //    for(int i=0; i<imglist.size(); i++)
    //    {
    //        QString str = imglist.at(i);
    //        qDebug() <<str;
    //    }
}

Dialog::~Dialog()
{
    delete ui;
    delete pix;
    delete timer;
}

void Dialog::preImgBtnSlot()
{
    imgnum = (imgnum + 5 - 1) % 5;
    //qDebug() << "图片" << imgnum;
    pix->load(imglist.at(imgnum)); // 加载imglist中的前一张图片
    ui->label->setPixmap(*pix); // 将图片设置到QLbel上
    ui->label_imgName->setText(QString::number(imgnum+1)); // 图片序号显示
}

void Dialog::nextImgBtnSlot()
{
    imgnum = (imgnum + 1) % 5;
    //qDebug() << "图片" << imgnum;
    pix->load(imglist.at(imgnum));
    ui->label->setPixmap(*pix);
    ui->label_imgName->setText(QString::number(imgnum+1));
}

void Dialog::randomImgBtnSlot()
{
    qint64 time = QDateTime::currentMSecsSinceEpoch();
    qsrand(time);
    int rand = qrand()%5; // 生成0-4的随机数

    imgnum = rand;
    //qDebug() << "随机图片" << imgnum;
    pix->load(imglist.at(imgnum));
    ui->label->setPixmap(*pix);
    ui->label_imgName->setText(QString::number(imgnum+1));
}

void Dialog::carouseBtnSlot()
{
    flag = !flag;
    if(flag)
    {
        timer->start(2000); // 启动定时器
        ui->carousePushBtn->setText("停止轮播");
    }
    else
    {
        timer->stop(); // 停止定时器
        ui->carousePushBtn->setText("开始轮播");
    }
}

void Dialog::imgCarouselSlot()
{
    imgnum = (imgnum + 1) % 5;
    pix->load(imglist.at(imgnum));
    ui->label->setPixmap(*pix);
    ui->label_imgName->setText(QString::number(imgnum+1));
}

void Dialog::updateTimeSlot()
{
    QDateTime now = QDateTime::currentDateTime();
    // 转换为固定格式
    QString time_text = now.toString("yyyy-MM-dd hh:mm:ss");
    //qDebug() << text; // "2023-10-20 16:00:44"
    ui->lcdDate->display(time_text);
}

main.cpp

#include "dialog.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();

    return a.exec();
}

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

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

相关文章

Spring framework day 03:Spring 整合 Mybatis(分页)

前言 在当今快速发展的软件开发领域&#xff0c;Java作为一种广泛使用的编程语言&#xff0c;以其强大的生态系统和丰富的框架而备受推崇。而在Java开发中&#xff0c;Spring框架几乎成为了事实上的标准&#xff0c;它为开发者提供了一种优雅且高效的方式来构建企业级应用程序…

CVE-2019-0708漏洞实战

使用命令&#xff1a;search 0708搜索exp脚本 搜索网段中主机漏洞 use auxiliary/scanner/rdp/cve_2019_0708_bluekeep 照例&#xff0c;show options 看一下配置 设置网段set RHOSTS x.x.x.x run运行就行了 使用攻击模块 use exploit/windows/rdp/cve_2019_0708_bluekee…

PAM从入门到精通(十八)

接前一篇文章&#xff1a;PAM从入门到精通&#xff08;十七&#xff09; 本文参考&#xff1a; 《The Linux-PAM Application Developers Guide》 PAM 的应用开发和内部实现源码分析 先再来重温一下PAM系统架构&#xff1a; 更加形象的形式&#xff1a; 六、整体流程示例 2.…

Java学习笔记(五)——数组、排序和查找

一、数组 数组可以存放多个同一类型的数据。数组也是一种数据类型&#xff0c;是引用类型。即数组就是一组数据。 &#xff08;一&#xff09;数组的使用 1、使用方式1——动态初始化 &#xff08;1&#xff09;数组的定义&#xff1a; 数据类型 数组名[] new 数据类型…

ubuntu安装rust教程

参考【Rust】Linux上安装Rust开发环境 sudo apt-get install curl# 注意&#xff0c;不开代理很可能下不到&#xff0c;一直报403 export RUSTUP_DIST_SERVERhttps://mirrors.ustc.edu.cn/rust-static export RUSTUP_UPDATE_ROOThttps://mirrors.ustc.edu.cn/rust-static/rustu…

【软考-中级】系统集成项目管理工程师 【19 项目收尾管理】

持续更新。。。。。。。。。。。。。。。 【第十九章】收尾管理 &#xff08;选择题1分&#xff09; 19.1 项目验收19.2 项目总结19.3系统维护19.3.1软件项目的后续工作19.3.2系统集成项目的后续工作 19.4 项目后评价1. 信息系统目标评价2. 信息系统过程评价3. 信息系统效益评价…

带温度的softmax

用pytorch写一下使用带有温度的softmax的demo import torch import torch.nn.functional as F# 定义带有温度的softmax函数 def temperature_softmax(logits, temperature1.0):return F.softmax(logits / temperature, dim-1)# 输入logits logits torch.tensor([[1.0, 2.0, 3.…

专题二:滑动窗口【优选算法】

滑动窗口&#xff1a; 什么时候用&#xff1f; 同向双指针&#xff08;找单调性&#xff09; 怎么用&#xff1f; 1&#xff09;用left、right指针维护窗口 2&#xff09;进窗口&#xff08;right指针&#xff0c;更新窗口内的值&#xff09; 3&#xff09;判断 出窗口&#xf…

LeetCode13——罗马数字转整数

解题思想&#xff1a; 前后指针 左边比右边小 做减法 左边比右边大 做加法 最后一个数字直接加。 package keepcoding.leetcode.leetcode13;public class Result02 {public static void main(String[] args) {int result romanToInt("XIV");System.out.println(re…

基于springboot实现java学习平台项目【项目源码+论文说明】

基于springboot实现java学习平台演示 摘要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括学习平台的网络应用&#xff0c;在外国学习平台已经是很普遍的方式&#xff0c;不过国内的管理平台可能还处于起步阶段。学习平台具…

链表收尾(8.2)

例题解析 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 1.拷贝节点插入原节点的后面&#xff08;核心&#xff09; 这样做的目的是方便找 random 节点&#xff0c;知道原节点可以找 random&#xff0c;知道上一个 random 可以找下一个 random 。 struct Node…

四、基本组件

1. Designer设计师 Designer程序是Qt官方推出的专为设计人员使用的UI设计工具&#xff0c;程序员可以使用此工具大幅降低UI设计的代码量。 Designer设计文件的格式是.ui&#xff0c;需要配合同名的头文件与源文件使用。.ui文件通常被称为界面文件&#xff0c;其内部是xml语法的…

(2023|ICML,LLM,标记掩蔽,并行解码)Muse:使用掩蔽生成 Transformer 的文本到图像生成

Muse: Text-To-Image Generation via Masked Generative Transformers 公众号&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要 1. 简介 2. 模型 2.1. 预训练文本编码器 2.2. 使用 V…

RabbitMQ队列及交换机的使用

目录 一、简单模型 1、首先控制台创建一个队列 2、父工程导入依赖 3、生产者配置文件 4、写测试类 5、消费者配置文件 6、消费者接收消息 二、WorkQueues模型 1、在控制台创建一个新的队列 2、生产者生产消息 3、创建两个消费者接收消息 4、能者多劳充分利用每一个消…

Power BI 傻瓜入门 2. Power BI的人员、方式和内容

本章内容包括&#xff1a; 识别潜在的企业Power BI用户使用Power BI解决数据生命周期问题区分使用Power BI生产的分析产品的类型 企业商业智能&#xff08;BI&#xff09;解决方案并非一刀切&#xff0c;这就是为什么像微软这样的供应商在Power BI利基市场的产品营销和分销中…

unity NPR 卡通渲染

文章目录 一、 介绍二、 素材准备三、 步骤四、 shader代码五、工程链接 一、 介绍 NPR是计算机图形学中的一类&#xff0c;即非真实感绘制(Non-photorealistic rendering)&#xff0c;主要用于模拟艺术式的绘制风格&#xff0c;也用于发展新绘制风格&#xff0c;形式一般是卡…

零基础Linux_20(进程信号)内核态和用户态+处理信号+不可重入函数+volatile

目录 1. 内核态和用户态 1.1 内核态和用户态概念 1.2 内核态和用户态转化 2. 处理信号 2.2 捕捉信号 2.2 系统调用sigaction 3. 不可重入函数 4. volatile关键字 5. SIGCHLD信号&#xff08;了解&#xff09; 6. 笔试选择题 答案及解析 本篇完。 1. 内核态和用户态…

气象台使用vr模拟仿真实训教学降低成本投入

气候仿真实验室用于模拟高低温、高湿、干燥、阳光光照、降雨、降雪、覆冰、雾天与强风等多种环境适应性试验等气候和环境条件&#xff0c;在环境试验中&#xff0c;温度、湿度、光照、降雨这些常见的仿真环境都很容易实现。而比较少见的雾天、强风、降雪等环境就比较难。因此为…

《动手学深度学习 Pytorch版》 9.8 束搜索

本节将介绍几大&#xff1a; 贪心搜索&#xff08;greedy search&#xff09;策略 穷举搜索&#xff08;exhaustive search&#xff09; 束搜索&#xff08;beam search&#xff09; 9.8.1 贪心搜索 贪心搜索已用于上一节的序列预测。对于输出序列的每一时间步 t ′ t t′…

【FPGA零基础学习之旅#16】嵌入式块RAM-双口ram的使用

&#x1f389;欢迎来到FPGA专栏~双口ram的使用 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能指正…