第一章 :图片查看器
QT 实现一个图片查看软件
目标实现
控件基本用法
实现流程
- 先使用ui文件实现一个简单的布局,使用label和lineedit和pushbutton
- 之后再widget.h文件添加
private slots:
void on_btnOpen_clicked();//注意这里如果要使用按钮这个控件,那么可以直接用On+控件名称(例如这个按钮的名称叫btnOpen)+事件
- 在widget.cpp文件中解释函数执行情况
void Widget::on_btnOpen_clicked()
{
QString filename = QFileDialog::getOpenFileName(this,"请选择图片","D:/","图片(*.png *.jpg);;");//当按下按钮,就会弹出D盘文件,选中的文件名称路径会保存
if(filename.isEmpty()){
return ;
}
ui->line_path->setText(filename);
ui->label_image->setPixmap((QPixmap(filename)));//在label标签中加载图片
}
优化图片查看器的代码
首先要在debug文件下创建一个config文件夹,在里面添加一个记录的文件,这样可以存储网址
void Widget::on_btnOpen_clicked()
{
QString config_path = qApp->applicationDirPath()+"/Config/Setting.ini";
std::unique_ptr<QSettings> pIniSet(new QSettings(config_path,QSettings::IniFormat));//用智能指针接受
//QSettings *pIniSet = new QSettings(config_path,QSettings::IniFormat);
QString lastPath =pIniSet->value("/LastPath/path").toString();
if(lastPath.isEmpty()){
lastPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
}
QString filename = QFileDialog::getOpenFileName(this,"请选择图片","D:/","图片(*.png *.jpg);;");
if(filename.isEmpty()){
return ;
}
ui->line_path->setText(filename);
QPixmap *pix =new QPixmap(filename);
pix->scaled(ui->label_image->size(),Qt::KeepAspectRatio);
ui->label_image->setScaledContents(true);
delete pix;
pix =nullptr;
ui->label_image->setPixmap(*pix);
int end =filename.lastIndexOf("/");
QString _path = filename.left(end);
pIniSet->setValue("/LastPath/path",_path);
}
补充知识
智能指针
当然可以!C++智能指针是一种特殊的指针类型,它可以自动管理内存,防止内存泄漏和悬空指针的问题。在C++中,主要有两种智能指针:std::unique_ptr和std::shared_ptr。
std::unique_ptr:这是一种独占式智能指针,它确保只有一个指针可以管理某个对象的内存。当std::unique_ptr被销毁时,它所管理的对象也会被自动删除。
下面是一个简单的例子:
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> ptr(new int(5));
std::cout << *ptr << std::endl; // 输出:5
// 使用`std::move()`将所有权转移给另一个`std::unique_ptr`
std::unique_ptr<int> ptr2 = std::move(ptr);
std::cout << *ptr2 << std::endl; // 输出:5
// `ptr`现在为空指针,因为所有权已经转移给`ptr2`
if (ptr == nullptr) {
std::cout << "ptr is nullptr" << std::endl;
}
// `ptr2`在作用域结束时会自动释放内存
return 0;
}
std::shared_ptr:这是一种共享式智能指针,它可以被多个指针共享管理同一个对象的内存。当没有任何指针再使用时,对象才会被删除。
下面是一个简单的例子:
#include <iostream>
#include <memory>
int main() {
std::shared_ptr<int> ptr(new int(10));
std::cout << *ptr << std::endl; // 输出:10
{
std::shared_ptr<int> ptr2 = ptr; // 复制`ptr`,共享所有权
std::cout << *ptr2 << std::endl; // 输出:10
}
// `ptr2`超出作用域后被销毁,但对象并未被删除
std::cout << *ptr << std::endl; // 输出:10
// `ptr`在作用域结束时会自动释放内存
return 0;
}
命名空间
lambda 表达式(建议看之前写的)
捕获方式
- 值捕获(value capture):
int x = 10;
auto valueCapture = [x](){
// 在Lambda表达式中访问x
std::cout << "值捕获:x = " << x << std::endl;
};
x = 20; // 修改外部变量x的值
valueCapture(); // 输出值捕获的结果
在这个例子中,Lambda表达式通过值捕获方式捕获了外部变量x的值,因此在Lambda表达式内部访问的是捕获时x的值,而不受外部x值的改变影响。
- 引用捕获(reference capture):
int y = 10;
auto referenceCapture = [&y](){
// 在Lambda表达式中访问y
std::cout << "引用捕获:y = " << y << std::endl;
};
y = 20; // 修改外部变量y的值
referenceCapture(); // 输出引用捕获的结果
在这个例子中,Lambda表达式通过引用捕获方式捕获了外部变量y的引用,因此在Lambda表达式内部访问的是外部y的引用,外部y值的改变会影响Lambda表达式内部对y的访问。
- 隐式捕获(implicit capture):
int z = 10;
auto implicitCapture = [&](){
// 在Lambda表达式中访问z
std::cout << "隐式捕获:z = " << z << std::endl;
};
z = 20; // 修改外部变量z的值
implicitCapture(); // 输出隐式捕获的结果
在这个例子中,Lambda表达式通过隐式捕获方式捕获了外部作用域中所有可见的变量,因此在Lambda表达式内部可以直接访问外部变量z,并且外部z值的改变也会影响Lambda表达式内部对z的访问。
通过这些例子,可以清楚地看到值捕获、引用捕获和隐式捕获之间的区别,以及它们在Lambda表达式中对外部变量访问的影响。
QT槽函数写法
另外一个就是他的槽函数用lambda去写
尽量不用,太乱
第五种用法就是之前图片查看器中使用的直接在函数名字上就上了on+对象名字+clicked(信号名字)