1 QT入门:实现一个简易的图片查看程序
1.1 布局思路
QLabel用来显示图片,QLabel显示"文件路径"
选中三个控件,右键->布局->水平布局
选中整体的空白处,右键->布局->垂直布局
选中容器,可以找到layoutStrech,设置其为1,8。也就是上面的3个空间所占空间与下面显示图片的label所占空间之比为1:8。
1.2 选择文件功能实现
界面功能都是.h头文件中声明,.cpp文件中实现。
private slots: //表示这是一个槽函数,private表示不可以被别的类使用 void on_btnSelect_clicked(); //按钮被按下的操作。btnSelect为按钮的名字。clicked表示激活该功能的按钮的动作为点击
绑定槽函数也可以使用connect函数实现,具体在后面的博客中可以看到
源文件中可以先进行调试,例如:
// 需要包含#include<qDebug>头文件 void Widget::on_btn_file_select_clicked(){ qDebug()<<"clike the button"<<endl; //创建一个匿名对象,并输出一句话 }
可以在控制台看到正常输出的语句。
而为了实现选择文件的功能,需要使用QFIleDialog类。
且我们要让显示的图片能显示,需要使用
1.3 QT中的配置文件
1.3.1 配置文件格式
以[]表示一个组(group),组中有多个键值对,等号左边是key,等号右边是value。如:
[main] CSDN_NAME=godspeed_lucip CSDN_TAG=C++ [other] CSDN_DISCRIPTION=Sharing [QT] QT_CLASS=QSettings QT_INI=config.ini
1.3.2 配置文件读写
配置文件可以用QSettings读写。
- 主要使用两个函数
QVariant value(const QString &key, const QVariant &defaultValue = QVariant())
- 第一个参数是键
- 第二个参数是默认值,也就是说如果没有读到值,就返回该默认值,如填-1 ,就返回-1
- 返回值是QVariant。在Qt中,QVariant是一个通用的值容器,它可以存储任意类型的数据,例如整数、字符串、列表等等。它的主要作用是提供一种通用的数据类型,方便在不同的函数、类、模块之间传递数据。
void setValue(const QString &key, const QVariant &value)
- 第一个参数是键(group+key)
- 第二个参数是值
1.4 记住上次打开的文件位置
每次打开文件都会从默认的文件路径中打开,因此需要实现这样的功能:按下选择文件按钮,可以直接跳转到上次打开的文件路径。实现此功能需要配置文件。
打开项目的配置目录,我的项目的路径为:
D:\VisualStudio\QtPrograms\ch1_7
则项目配置目录为:
D:\VisualStudio\QtPrograms\build-ch1_7-Desktop_Qt_5_15_2_MSVC2019_32bit-Debug\debug
新建一个config目录。再新建一个Settings.ini配置文件,创建group为last_path,添加键值对:
此处写或不写都可以,因为最后在写入时也会进行创建
[last_path] path=
1.4.1 qApp
qApp
是一个指向QApplication
或QGuiApplication
对象的全局指针,可以理解为就是指向窗口的指针。
QApp->appllicationDirPath()得到的路径始终都是可执行文件所在的绝对路径。而可执行文件实际上就在build-ch1_7-Desktop_Qt_5_15_2_MSVC2019_32bit-Debug\debug文件路径中。
1.4.2 QStandardPaths
系统标准路径类,也就是用户的特定目录或系统的配置目录。比如在Windows系统中的“我的文档”,“视频”,“图片”等目录位置。
不同的操作系统中,其标准路径都不一样,但是在Qt中,我们却可以通过这个类,直接获取到对应路径(就算没有也会被创建)。
共有两种方式获取到路径:
//都是静态方法 static QString writableLocation(StandardLocation type); static QStringList standardLocations(StandardLocation type);
//下面列举出标准路径的枚举 enum StandardLocation { DesktopLocation, //桌面路径 DocumentsLocation, //文档路径 FontsLocation, //字体路径 ApplicationsLocation, MusicLocation, MoviesLocation, PicturesLocation, //图片路径 TempLocation, HomeLocation, DataLocation, CacheLocation, GenericDataLocation, RuntimeLocation, ConfigLocation, DownloadLocation, GenericCacheLocation, GenericConfigLocation, AppDataLocation, AppConfigLocation, AppLocalDataLocation = DataLocation }; Q_ENUM(StandardLocation)
参考:系统标准路径类详解——QStandardPaths - 知乎 (zhihu.com)
1.5 让图片自适应
假设要让一个QLabel来显示一张图片。大致思路是重新设置图片和label的大小,比设置图片居中即可。
为了保证图片保持原长宽比,可以计算图片宽与label宽、图片长和label长的比值,选择较小的比值作为最终的缩放因子(如果选择较大的比值,就会导致图片放缩之后过大)。
之后根据缩放因子调整图片的大小即可。具体做法见代码注释。
1.6 程序效果
1.7 完整代码
widget.cpp:
#include "widget.h" #include "ui_widget.h" #include<QDebug> #include<QFileDialog> #include<QString> #include<QSettings> #include<QStandardPaths> #include<QImage> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); } Widget::~Widget() { delete ui; } void Widget::on_btnSelect_clicked(){ QString init_path = qApp->applicationDirPath()+"/config/Settings.ini"; //获取配置文件的路径 //`qApp`是一个指向`QApplication`或`QGuiApplication`对象的全局指针,可以理解为就是指向窗口的指针。 // qDebug()<<init_path; //测试app_path是否正常 // 根据ini件路径新建QSettings类 QSettings *pSetIni = new QSettings(init_path,QSettings::IniFormat); //获取ini配置文件中last_path组中的键值对path QString last_path = pSetIni->value("/last_path/path").toString(); if(last_path==NULL){ //如果获取到的值为空,也就是第一次使用该键,就给其设置一个默认的路径 //对于默认的文件路径,想让其为windows的图片文件夹,可以使用系统标准路径类 last_path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); // qDebug()<<last_path; //输出结果为:"C:/Users/86186/Pictures" } //前面已经获取到了打开文件夹的路径,下面就要获取文件 QString file_path = QFileDialog::getOpenFileName(this, "选择图片进行展示",last_path, "文件(*.png#pic_center *.jpg);;"); //要从file_name中提取出文件所在文件夹路径。注意文件路径的格式:C:/Users/86186/Pictures/pic.png#pic_center int index = file_path.lastIndexOf("/"); //获取到最后一个/的位置 QString dir_path = file_path.left(index); //使用setValue方法写入Ini文件。第一个参数为group+key。第二个参数为value pSetIni->setValue("/last_path/path",dir_path); //记得释放堆区的数据、 delete pSetIni; pSetIni=NULL; //让其指向空,防止野指针 if(file_path.isEmpty()){ //如果文件名为空 return ; } this->ui->fileNameDisp->setText(file_path); //将文件名显示出来 //使图片自适应窗口,同时保证图片自身的比例 QImage *label_image = new QImage(file_path); //使用QImage打开图片 QImage pil_image = this->resize_image(this->ui->imageDisp->width(), this->ui->imageDisp->height(), *label_image); QPixmap pixmap = QPixmap::fromImage(pil_image); //根据QImage对象创建QPixmap对象 this->ui->imageDisp->resize(pixmap.width(),pixmap.height()); this->ui->imageDisp->setPixmap(pixmap); this->ui->imageDisp->setAlignment(Qt::AlignCenter); //设置图片居中显示 delete label_image; //释放堆区数据 label_image = NULL; } QImage Widget::resize_image(int width,int height,QImage image){ //调整图片的大小 //width:要适应的窗口的宽 //height:要适应的窗口的长 //image:图片对象 int image_width = image.width(); int image_height = image.height(); //获取原始图片的长和宽 float f1 = 1.0*width/image_width; float f2 = 1.0 * height/image_height; float factor = f1<f2?f1:f2; //去最小的因子,也就是最多放缩多少倍 width = int(image_width * factor); height = int(image_height * factor); //对原图的大小进行放缩 return image.scaled(width, height); }
百度网盘链接:提取码:ikun
2 总结
在代码的舞台上翩翩起舞, Qt,如诗如画,编织梦的彩虹。
跨越平台的轻盈舞姿, 文档的琴音,灵感的涟漪。
模块的花瓣,细腻而丰满, 开发者的心灵,在那里盛开。
清新而深邃,如林中明月, Qt,用优雅的笔触,谱写未来的篇章。
渴望挑战Qt的学习路径和掌握进阶技术?不妨点击下方链接,一同探讨更多Qt的奇迹吧。我们推出了引领趋势的💻QT专栏:《QT从基础到进阶》 ,旨在深度探索Qt的实际应用和创新。🌐🔍