zoukankan      html  css  js  c++  java
  • Qt 编程指南 8 显示静态小图片和动态大图片

    显示控件概览

     图片浏览示例

    第一行是一个标签控件,objectName 为 labelShow,文本内容清空,因为是用来显示图片用的。

     主界面第二行的控件是四个普通按钮

    第一个按钮文本是 "打开图片",objectName 为 pushButtonOpenPic;
    第二个按钮文本是 "打开动态图",objectName 为 pushButtonOpenMov;
    第三个按钮文本是 "播放",objectName 为 pushButtonStart;
    第四个按钮文本是 "停止",objectName 为 pushButtonStop。

    水平滑动条,objectName 为 horizontalSlider。这个水平滑动条适用于显示动态图播放进度的

     main.cpp

    #include "Qt_Show.h"
    #include <QtWidgets/QApplication>
    #include <QBitmap>
    
    
    int main(int argc, char *argv[])
    {
    	QApplication a(argc, argv);
    	Qt_Show w;
    
    	QPixmap pixmap("images/timg2.jpg");   //  读取图片
    	QPalette   palette;
    	palette.setBrush(w.backgroundRole(), QBrush(pixmap));  // 将图片设置在指定窗口
    	w.setPalette(palette);
    	//w.setMask(pixmap.mask());  //可以将图片中透明部分显示为透明的
    	w.setAutoFillBackground(true);   // 自动充满
    
    	w.show();
    	return a.exec();
    }
    

     窗口头文件

    #pragma once
    
    
    
    #include <QtWidgets/QMainWindow>
    #include "ui_Qt_Show.h"
    
    #include <QPixmap>  //像素图
    #include <QMovie>   //动态图
    #include <QImageReader> //可以打开图片或者查看支持的图片格式
    
    class Qt_Show : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    	Qt_Show(QWidget *parent = Q_NULLPTR);
    	~Qt_Show();
    
    public slots:
    	//接收出错的信号
    	void RecvPlayError(QImageReader::ImageReaderError error);
    	//接收播放时帧号变化
    	void RecvFrameNumber(int frameNumber);
    
    private slots:
    	void on_pushButtonOpenPic_clicked();
    
    	void on_pushButtonOpenMov_clicked();
    
    	void on_pushButtonStart_clicked();
    
    	void on_pushButtonStop_clicked();
    
    
    private:
    	Ui::Qt_ShowClass ui;
    
    	//像素图指针
    	QPixmap *m_pPixMap;
    	//动态图指针
    	QMovie *m_pMovie;
    	//是否为动态图
    	bool m_bIsMovie;
    	//动态图是否在播放中,如果在播放中,那么循环播放
    	bool m_bIsPlaying;
    
    	//清除函数,在打开新图之前,清空旧的 打开新图之前,清理旧的像素图、动态图对象,并重置两个标志位变量。
    	void ClearOldShow();
    
    
    
    }; 

      窗体实体

    #include "Qt_Show.h"
    
    
    #include <QDebug>
    #include <QFileDialog>  //打开文件对话框
    #include <QScrollArea>  //为标签添加滚动区域
    #include <QMessageBox>  //消息框
    
    
    Qt_Show::Qt_Show(QWidget *parent)
    	: QMainWindow(parent)
    {
    	ui.setupUi(this);
    
    
    	//初始化成员变量
    	m_pPixMap = NULL;
    	m_pMovie = NULL;
    	m_bIsMovie = false;
    	m_bIsPlaying = false;
    
    	//获取标签矩形
    	QRect rcLabel = ui.labelShow->geometry();
    	//为标签添加滚动区域,方便浏览大图
    	QScrollArea *pSA = new QScrollArea(this);   //该对象交给主窗体自动管理,不用手动删除
    	//把标签填充到滚动区域里
    	pSA->setWidget(ui.labelShow);
    	//设置滚动区域占据矩形
    	pSA->setGeometry(rcLabel);
    
    	//打印支持的图片格式
    	qDebug() << QImageReader::supportedImageFormats();
    	//打印支持的动态图格式
    	qDebug() << QMovie::supportedFormats();
    
    }
    
    
    
    Qt_Show::~Qt_Show()
    {
    	//手动清空
    	ClearOldShow();
    	//原有的代码
    //	delete ui;
    }
    
    void Qt_Show::ClearOldShow()
    {
    	//清空标签内容
    	ui.labelShow->clear();
    	//像素图不空就删除
    	if (m_pPixMap != NULL)
    	{
    		//删除像素图
    		delete m_pPixMap;   m_pPixMap = NULL;
    	}
    	//如果短片不为空,就删除
    	if (m_pMovie != NULL)
    	{
    		//如果正在播放则停止
    		if (m_bIsPlaying)
    		{
    			m_pMovie->stop();
    		}
    		//删除动态图
    		delete m_pMovie;    m_pMovie = NULL;
    	}
    	//标志位重置
    	m_bIsMovie = false;
    	m_bIsPlaying = false;
    }
    
    
    
    void Qt_Show::on_pushButtonOpenPic_clicked()
    {
    	QString strFileName;    //文件名
    	strFileName = QFileDialog::getOpenFileName(this, tr("打开静态图片"), "",
    		"Pictures (*.bmp *.jpg *.jpeg *.png *.xpm);;All files(*)");
    	if (strFileName.isEmpty())
    	{
    		//文件名为空,返回
    		return;
    	}
    	//清空旧的图片或短片
    	ClearOldShow();
    	//打印文件名
    	qDebug() << strFileName;
    
    	//新建像素图
    	m_pPixMap = new QPixmap();
    	//加载
    	if (m_pPixMap->load(strFileName))
    	{
    		//加载成功
    		//设置给标签
    		ui.labelShow->setPixmap(*m_pPixMap);
    		//设置标签的新大小,与像素图一样大
    		ui.labelShow->setGeometry(m_pPixMap->rect());
    		//设置 bool 状态
    		m_bIsMovie = false;     //不是动态图
    		m_bIsPlaying = false;   //不是动态图播放
    	}
    	else
    	{
    		//加载失败,删除图片对象,返回
    		delete m_pPixMap;   m_pPixMap = NULL;
    		//提示失败
    		QMessageBox::critical(this, tr("打开失败"),
    			tr("打开图片失败,文件名为:
    %1").arg(strFileName));
    	}
    }
    
    void Qt_Show::on_pushButtonOpenMov_clicked()
    {
    	QString strFileName;    //文件名
    	strFileName = QFileDialog::getOpenFileName(this, tr("打开动态图片"), "",
    		"Movies (*.gif *.mng);;All files(*)");
    	if (strFileName.isEmpty())
    	{
    		//文件名为空,返回
    		return;
    	}
    	//清除旧的图片或短片
    	ClearOldShow();
    	//打印文件名
    	qDebug() << strFileName;
    
    	//新建动态图
    	m_pMovie = new QMovie(strFileName);
    	//判断是否动态图文件可用
    	if (!m_pMovie->isValid())
    	{
    		//不可用
    		QMessageBox::critical(this, tr("动态图不可用"),
    			tr("动态图格式不支持或读取出错,文件名为:
    %1").arg(strFileName));
    		//清除
    		delete m_pMovie;    m_pMovie = NULL;
    		return; //不可用就直接返回
    	}
    
    	//动态图的总帧数
    	int nCount = m_pMovie->frameCount(); //如果动态图格式不支持计数,那么会返回 0
    	//打印帧数
    	qDebug() << tr("总帧数:%1").arg(nCount);
    	//如果有统计帧数,那就设置滑动条上限
    	if (nCount > 0)
    	{
    		ui.horizontalSlider->setMaximum(nCount);
    	}
    	else
    	{
    		//获取不到帧数,默认当作 100
    		ui.horizontalSlider->setMaximum(100);
    	}
    
    	//把动态图设置给标签
    	ui.labelShow->setMovie(m_pMovie);
    	//修改 bool 状态
    	m_bIsMovie = true;
    	m_bIsPlaying = false;   //还没点击播放开始的按钮
    	//待续
    
    	//关联播放时的信号
    	//播放出错信号
    	connect(m_pMovie, SIGNAL(error(QImageReader::ImageReaderError)),
    		this, SLOT(RecvPlayError(QImageReader::ImageReaderError)));
    	//播放的帧号变化信号
    	connect(m_pMovie, SIGNAL(frameChanged(int)),
    		this, SLOT(RecvFrameNumber(int)));
    
    	//将动态图片跳转到起始帧
    	if (m_pMovie->jumpToFrame(0))
    	{
    		//跳转成功
    		//对于打头的帧,设置标签的矩形为帧的矩形
    		ui.labelShow->setGeometry(m_pMovie->frameRect());
    	}
    	//如果跳转失败,槽函数 RecvPlayError() 会提示出错
    }
    
    //播放开始按钮
    void Qt_Show::on_pushButtonStart_clicked()
    {
    	if (!m_bIsMovie)   //不是动态图
    	{
    		return;
    	}
    	if (m_bIsPlaying)  //已经在播放了
    	{
    		return;
    	}
    	//播放动态图
    	m_bIsPlaying = true;    //开始播放状态
    	m_pMovie->start();  //播放
    	//打印动态图默认的播放循环轮数,0 代表不循环,-1 代表无限循环
    	qDebug() << tr("循环计数:%1").arg(m_pMovie->loopCount());
    }
    
    //停止播放按钮
    void Qt_Show::on_pushButtonStop_clicked()
    {
    	if (!m_bIsMovie)   //不是动态图
    	{
    		return;
    	}
    	if (!m_bIsPlaying) //没有处于播放状态
    	{
    		return;
    	}
    	//停止播放
    	m_bIsPlaying = false;
    	m_pMovie->stop();
    }
    
    //接收播放错误信号
    void Qt_Show::RecvPlayError(QImageReader::ImageReaderError error)
    {
    	//打印
    	qDebug() << tr("读取动态图错误的代码:%1").arg(error);
    	//提示播放出错
    	QMessageBox::critical(this, tr("播放出错"),
    		tr("播放动态图出错,文件名为:
    %1").arg(m_pMovie->fileName()));
    	//回到停止状态
    	m_bIsPlaying = false;
    }
    
    //接收帧号变化信号
    void Qt_Show::RecvFrameNumber(int frameNumber)
    {
    	ui.horizontalSlider->setValue(frameNumber);
    }
    
    •   问题1  都是图片,opensuse.png 能打开,opensuse.jpg 打开出错,这是为什么呢?
      用这两张图片举例,不是为了说明 png 格式比 jpg 好,也不是为了说明我们例子代码有问题,
      而是为了说明有些错误不在程序本身!
      我们举例的 opensuse.png 和 opensuse.jpg 两张图片文件的数据是一模一样的,就是复制了一份,改了个扩展名而已。
      opensuse 的图片原本就是 PNG 格式的,在下载的时候错误地保存为 opensuse.jpg。虽然操作系统的图片查看器、之前的 QTextBrowser 示例都能浏览这个错误扩展名的图片,但是 QPixmap::load() 函数根据 jpg 扩展名加载 opensuse.jpg 时出现了错误,因为这张图根本不是 jpg 图片。
      这里打开 opensuse.jpg 出错,就是因为图片扩展名错了,与程序本身没关系。

      那么 5.3.4 QTextBrowser 示例怎么能正确显示 opensuse.jpg 呢?那是因为它没有用 QPixmap::load() 函数加载图片,而是 QImage::​loadFromData() 函数,感兴趣的读者可以看看 QImage::​loadFromData() 函数帮助文档,它是直接从文件数据头判断文件格式,而不管扩展名是什么,因此能正确显示扩展名错误的图片。
  • 相关阅读:
    firefox安装教程
    shell脚本介绍
    vue 图片引入
    vscode 常用插件
    vscode 打不开chrome浏览器解决方案
    win10 wifi 密码查看
    爽文 主角如 石昊 白小纯 方行 秦牧 楚风
    codepen, jsrun 使用iframe嵌入
    uniapp 自定义扫一扫页面
    数组(遍历删除多个元素)
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/7476097.html
Copyright © 2011-2022 走看看