Qt(资源库和按钮组)
这一节是对上一节的补充,上一节提到QLabel类和QAabstractButton类,这节内容:
1.如设置资源库,使用资源设置图片
2. 使用按钮组管理多个按钮。
一、资源库
1. 资源库作用
Qt的资源库(Resource System,.qrc文件)可以将图片、音频、UI文件等外部资源文件打包进项目,成为项目的一部分。
2. 特点
(1). 虚拟路径机制
通过.qrc文件为资源分配虚拟路径(如 :/images/logo.png),在代码中用虚拟路径访问资源,而不是硬编码磁盘路径。
(2). 跨平台无忧
资源被打包进可执行文件或资源文件,无论项目拷贝到哪个环境、系统或设备,只要可执行文件在,资源都能被正确访问,不会因路径变化或缺失而出错。
(3). 使用方便
在项目的任何地方都可以通过虚拟路径访问资源(如QPixmap(":/images/logo.png")),无需关心实际文件存放位置。
(4). 项目分发更简单
只需分发可执行文件(或带资源的安装包),不必单独拷贝图片等资源文件,避免“找不到图片”等问题。
(5). 资源安全性
资源打包后不易被随意修改或替换,提升了项目的完整性和安全性。
3. 添加资源库


(2) 在Qt Creator中选中项目名称,鼠标右键,点击添加“新文件”
(3)在弹出的窗口中,选择添加文件类型:





4. 使用资源库添加静态图片
还记得上一节使用的QLabel类,它是一种显示文字和图片的组件,这里我们就添加一个label组件,再给它设上图片:
(1) 使用ui界面直接设置:
先拖一个label:
选中label组件,选择左下角属性直接设置图片:

其他属性可以参考上一节自行修改。
(2)使用代码添加图片

2. 如果通过代码添加,需要用到头文件#include<QPixmap>头文件,图片类头文件。函数:
// 图片类构造函数
// 参数1:图片资源路径(qrc文件选中图片资源鼠标右键复制)
// 参数2:样板格式,使用默认值即可
// 参数3:图片颜色格式,也是使用默认即可
QPixmap::QPixmap(const QString & fileName, const char * format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor)
// 缩放
// 参数1:QSize类型对象,表示目标尺寸。需要添加头文件#include<QSize>
// 参数2:缩放模式,三种。是一个枚举
// 参数3:以速度优先还是质量优先,两种模式,默认以速度优先,也是一个枚举
// 返回值:转换后的QPixmap对象
QPixmap QPixmap::scaled(const QSize & size, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode = Qt::FastTransformation) const
// 构造函数
// 图片的宽度和高度
QSize::QSize(int width, int height)
复制资源虚拟路径:
代码:
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPixmap>
#include <QSize>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{Q_OBJECTpublic:explicit Dialog(QWidget *parent = 0);~Dialog();private:Ui::Dialog *ui;
};#endif // DIALOG_H
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{ui->setupUi(this);// 创建一个图片对象// 参数:图片的资源路径QPixmap pic(":/new/prefix1/picture1/idol.png");// 定义QSize对象QSize size(ui->label->width(),ui->label->height());// 缩放pic = pic.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation);// 使用界面文件中的组件对象ui->label->setPixmap(pic);}Dialog::~Dialog()
{delete ui;
}
5. 使用资源库添加动态图
(1)需要将我们的动态图,放到项目的工作目录中,并且进行命名.gif
(2)添加完成后,需要将动态图,加载到资源文件中。


补充:1.别忘了再创建一个label,改名为labelGif。
2.只有第一次创建资源文件才需要重构项目
QMovie电影类:
如果需要播放动态图,需要用到电影类,需要添加头文件#include<QMovie>。
// 电影类构造函数,堆区创建
// 参数1 :资源路径
// 参数2:输出模式
// 参数3:基类指针,看到基类指针,就知道要创建堆内存对象
QMovie::QMovie(const QString & fileName, const QByteArray & format = QByteArray(), QObject * parent = 0)
代码:
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPixmap>
#include <QSize>
#include <QMovie>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{Q_OBJECTpublic:explicit Dialog(QWidget *parent = 0);~Dialog();private:Ui::Dialog *ui;QMovie *movie; // 电影类指针
};#endif // DIALOG_H
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{ui->setupUi(this);// 创建一个图片对象// 参数:图片的资源路径QPixmap pic(":/new/prefix1/picture1/idol.png");// 定义QSize对象QSize size(ui->label->width(),ui->label->height());// 缩放pic = pic.scaled(size,Qt::KeepAspectRatio,Qt::SmoothTransformation);// 使用界面文件中的组件对象ui->label->setPixmap(pic);// 创建电影类对象movie = new QMovie(":/new/prefix1/picture1/gege.gif");// 给QLabel设置电影ui->labelGif->setMovie(movie);// 播放电影movie->start();}Dialog::~Dialog()
{delete ui;
}
效果:
注意:
1.UI界面好用但是图片一定要在外面处理好在放到项目中,假如label是50*50的,你的图片是1000*1000的,即使你用了填充,但是还是占内存,所以根据你需要可以调节图片大小后再放入项目中。
2.经过我长时间体验,我推荐几个软件处理图片:
(1)Windows系统自带的照片,为什么不用图画,问就是不好用。这个自带软件主要功能就是调节图片大小,可以按比例调大调小不会裁剪你的图片;还有一个主要功能就是抠图,扣掉背景,这个在写飞机大战等小游戏的时候,可以不让图片背景挡住主背景只显露飞机,就不是一个方框框框了。
(2)美图秀秀,算是不使用vip功能比较多的软件了
二、按钮组
1. 简介:
1.1 介绍
QButtonGroup组件
可以使用QB uttonGroup组件对多个按钮进行分组,这是一个逻辑分组,没有任何的ui效果。其主要的目的是使用一个信号槽同时监控多个按钮对象的状态。
QButtonGroup继承于QOBject并非QWidget,所以它是不可见的,用户无法从这个窗口中看到此组件。
1.2 作用
- 分组管理:可以把多个按钮归为一组,便于统一处理。
- 互斥选择:配合QRadioButton实现单选功能(同组内只能选一个)。
- 信号统一:可以通过QButtonGroup的信号(如buttonClicked(int id))统一响应组内按钮的点击事件。
- 分配ID:可以为每个按钮分配唯一ID,便于区分和处理。
1.3 函数:
构造函数:
// 构造函数 堆区创建
QButtonGroup::QButtonGroup(QObject * parent = 0)
添加按钮进按钮组:
// 给按钮组,添加要管理的按钮
// 参数1:添加的实际的按钮
// 参数2:序号ID
void QButtonGroup::addButton(QAbstractButton * button, int id = -1)
信号函数:
参数中表示当前触发的按钮对象本身,
表示当前触发的按钮序号。在触发信号后,可以把这个参数传入槽函数,槽函数中可以使用sender() 判断当前触发信号的按钮是按钮组中的哪个。
2. 练习:
拉几个组建
代码:
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QDebug>
#include <QButtonGroup>namespace Ui {
class Dialog;
}class Dialog : public QDialog
{Q_OBJECTpublic:explicit Dialog(QWidget *parent = 0);~Dialog();private:Ui::Dialog *ui;QButtonGroup *btp;private slots:void toggledSlot(bool);void buttonToggledSlot(int,bool);
};#endif // DIALOG_H
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{ui->setupUi(this);connect(ui->radioButton,SIGNAL(toggled(bool)),this,SLOT(toggledSlot(bool)));// 创建组件对象btp = new QButtonGroup(this);btp->addButton(ui->checkBox,1);btp->addButton(ui->checkBox_2,2);btp->addButton(ui->checkBox_3,3);btp->addButton(ui->checkBox_4,4);// 注意,我们的按钮组件,是可以多选的,但是按钮组里的组件,默认是互斥的。// 所以,要解除按钮组的互斥属性btp->setExclusive(false);connect(btp,SIGNAL(buttonToggled(int,bool)),this,SLOT(buttonToggledSlot(int,bool)));}Dialog::~Dialog()
{delete ui;
}void Dialog::toggledSlot(bool checked)
{if(checked){qDebug() << "超意兴被选中了";}else{qDebug() << "不选超意兴了";}
}void Dialog::buttonToggledSlot(int id, bool checked)
{if(id == 1){if(checked){qDebug() << "8+1被选中了";}else{qDebug() << "不选8+1了";}}if(id == 2){if(checked){qDebug() << "雷花-勇闯天堂被选中了";}else{qDebug() << "不选雷花-勇闯天堂了";}}if(id == 3){if(checked){qDebug() << "青鸟被选中了";}else{qDebug() << "不选青鸟了";}}if(id == 4){if(checked){qDebug() << "7天被选中了";}else{qDebug() << "不选7天了";}}else{}
}
注意:
- QButtonGroup本身不负责界面布局,只负责逻辑分组。
- QButtonGroup可以管理不同类型的按钮,但常用于同类型按钮的分组。