Qt 实现的简易本地图片浏览器

非常好的code,转载自:http://www.cnblogs.com/craigtao/p/6640470.html

在做项目的时候,记录一些小功能模块,这是在开发视频平台的时候,需要写的一个模块(本地图片浏览)

需要用的技术点:

1、文件过滤(支持模糊搜索),使用Qt内置正则

2、图片加载显示

3、信号和槽

 将图像模糊搜索列表和显示图像分别封装成各自的widget类

直接上代码:

searchfilter.h

#ifndef SEARCHFILTER_H
#define SEARCHFILTER_H

#include 

class QLineEdit;
class QListView;
class QStringListModel;
class QSortFilterProxyModel;
class QItemSelection;

class SearchFilter : public QWidget
{
    Q_OBJECT
public:
    explicit SearchFilter(QWidget *parent = 0);
    void Init(const QString &dir_str, const QStringList &filter_list);
    void SetCurrentSelectFile_Prev();
    void SetCurrentSelectFile_Next();
    
signals:
    //发送当前选中的文件名
    void signal_current_select_file(const QString& file_name);
    
private slots:
    void textChanged_input_edit(const QString& text);
    void onDoubleClick_listView(const QModelIndex& index);
    void selectChanged_listView(const QItemSelection& selection);
    
private:
    QString m_dir_str;
    QLineEdit* m_input_edit;
    QListView* m_file_list_view;
    QStringListModel* m_string_list_model;
    QSortFilterProxyModel* m_proxy_model;
};

#endif // SEARCHFILTER_H
searchfilter.cpp

#include "searchfilter.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

SearchFilter::SearchFilter(QWidget *parent) : QWidget(parent)
{
    //输入框
    m_input_edit = new QLineEdit();
    m_input_edit->setMinimumHeight(35);
    //文件列表
    m_file_list_view = new QListView();
    
    m_string_list_model = new QStringListModel();
    m_proxy_model = new QSortFilterProxyModel();
    
    QVBoxLayout* main_layout = new QVBoxLayout();
    main_layout->addWidget(m_input_edit);
    main_layout->addWidget(m_file_list_view);
    
    this->setLayout(main_layout);
    
    connect(m_input_edit, SIGNAL(textChanged(QString)), this, SLOT(textChanged_input_edit(QString)));
    connect(m_file_list_view, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(onDoubleClick_listView(QModelIndex)));
    
    //这里绑定了选中变化时发生事件
    connect(m_file_list_view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
            this, SLOT(selectChanged_listView(QItemSelection)));
}

//设置搜索过滤目录和文件后缀
void SearchFilter::Init(const QString &dir_str, const QStringList &filter_list)
{
    m_dir_str = dir_str;
    
    QDir* dir = new QDir(dir_str);
    dir->setNameFilters(filter_list);
    
    QStringList file_list = dir->entryList();
    
    m_string_list_model->setStringList(file_list);
    m_proxy_model->setSourceModel(m_string_list_model);
    
    m_file_list_view->setModel(m_proxy_model);
    m_file_list_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
    
    //设置当前选中行 0行 0列
    QModelIndex index = m_proxy_model->index(0, 0);
    m_file_list_view->setCurrentIndex(index);
}

//选上一个
void SearchFilter::SetCurrentSelectFile_Prev()
{
    QModelIndex curr_index = m_file_list_view->currentIndex();
    int curr_row = curr_index.row();
    
    if (curr_row == 0) {
        QMessageBox::information(this, tr("提示"), tr("前面没有了"), QMessageBox::Ok);
        return ;
    }
    
    curr_row = curr_row - 1;
    
    curr_index = m_proxy_model->index(curr_row, 0);
    m_file_list_view->setCurrentIndex(curr_index);
    
    //当前选中
    curr_index = m_file_list_view->currentIndex();
    QString picture_name = curr_index.data().toString();
    QString picture_path = m_dir_str + picture_name;
    
    emit signal_current_select_file(picture_path);
}

//选中下一个
void SearchFilter::SetCurrentSelectFile_Next()
{
    QModelIndex curr_index = m_file_list_view->currentIndex();
    int curr_row = curr_index.row();
    
    int rows = m_proxy_model->rowCount();
    
    if (curr_row == (rows - 1)) {
        QMessageBox::information(this, tr("提示"), tr("后面没有了"), QMessageBox::Ok);
        return ;
    }
    
    curr_row = curr_row + 1;
    
    curr_index = m_proxy_model->index(curr_row, 0);
    m_file_list_view->setCurrentIndex(curr_index);
    
    //当前选中
    curr_index = m_file_list_view->currentIndex();
    QString picture_name = curr_index.data().toString();
    QString picture_path = m_dir_str + picture_name;
    
    emit signal_current_select_file(picture_path);
}

//QLineEdit输入发生变化事件
void SearchFilter::textChanged_input_edit(const QString &text)
{
    //正则方式
    QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(
                QRegExp::FixedString);
    QRegExp regExp(text, Qt::CaseInsensitive, syntax);
    m_proxy_model->setFilterRegExp(regExp);
}

//listview双击事件
void SearchFilter::onDoubleClick_listView(const QModelIndex &index)
{
    QString picture_name = index.data().toString();
    QString picture_path = m_dir_str + picture_name;
    
    emit signal_current_select_file(picture_path);
}

//选中发生变化时  不知道为什么这里没有触发(如果哪位前辈知道原因,指导一下)
void SearchFilter::selectChanged_listView(const QItemSelection &selection)
{
    QModelIndex index = m_file_list_view->currentIndex();
    QString picture_name = index.data().toString();
    QString picture_path = m_dir_str + picture_name;

  emit signal_current_select_file(picture_path);
}
imageviewer.h

#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H

#include 
#include 

class QLabel;
class QScrollArea;
class QPushButton;
class QHBoxLayout;
class QVBoxLayout;
class QScrollArea;

class ImageViewer : public QWidget
{
    Q_OBJECT
public:
    explicit ImageViewer(QWidget *parent = 0);
    
    bool loadFile(const QString& fileName);
    
private:
    void setImage(const QImage &newImage);
    
signals:
    void signal_prev();
    void signal_next();
    
private slots:
    void on_click_btn_zoom_out();
    void on_click_btn_zoom_in();
    void on_click_btn_prev();
    void on_click_btn_next();
    
private:
    void zoomOut();
    void zoomIn();
    void scaleImage(double factor);
    
private:
    double scaleFactor;
    QImage image;
    QLabel* image_label; //显示图片
    QScrollArea* scrollArea;
    
    //主界面layout
    QVBoxLayout* main_layout;
    
    //按钮工具
    QHBoxLayout* tool_layout;
    QPushButton* btn_prev;
    QPushButton* btn_next;
};

#endif // IMAGEVIEWER_H
imagevierer.cpp

#include "imageviewer.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 

ImageViewer::ImageViewer(QWidget *parent) : QWidget(parent)
{
    image_label = new QLabel();
    image_label->setBackgroundRole(QPalette::Base);
    image_label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    image_label->setScaledContents(true);
    
    //scrollArea = new QScrollArea();
    //scrollArea->setBackgroundRole(QPalette::Dark);
    //scrollArea->setWidget(image_label);
    //scrollArea->setVisible(false);
    
    main_layout = new QVBoxLayout(this);
    main_layout->addWidget(image_label);
    
    btn_prev = new QPushButton("上一张");
    //QPushButton* btn_zoom_out = new QPushButton("-");
    //QPushButton* btn_zoom_in = new QPushButton("+");
    btn_next = new QPushButton("下一张");
    
    QSpacerItem* item_left = new QSpacerItem(75, 40, QSizePolicy::Expanding, QSizePolicy::Minimum);
    QSpacerItem* item_right = new QSpacerItem(75, 40, QSizePolicy::Expanding, QSizePolicy::Minimum);
    
    tool_layout = new QHBoxLayout();
    tool_layout->addSpacerItem(item_left);
    tool_layout->addWidget(btn_prev);
    //tool_layout->addWidget(btn_zoom_out);
    //tool_layout->addWidget(btn_zoom_in);
    tool_layout->addWidget(btn_next);
    tool_layout->addSpacerItem(item_right);
    
    main_layout->addLayout(tool_layout);
    
    this->setLayout(main_layout);
    this->setStyleSheet("background-color: rgb(167, 175, 159);");
    
    //connect(btn_zoom_out, SIGNAL(clicked(bool)), this, SLOT(on_click_btn_zoom_out()));
    //connect(btn_zoom_in, SIGNAL(clicked(bool)), this, SLOT(on_click_btn_zoom_in()));
    connect(btn_prev, SIGNAL(clicked(bool)), this, SLOT(on_click_btn_prev()));
    connect(btn_next, SIGNAL(clicked(bool)), this, SLOT(on_click_btn_next()));
}

bool ImageViewer::loadFile(const QString &fileName)
{
    QImageReader reader(fileName);
    reader.setAutoTransform(true);
    const QImage newImage = reader.read();
    
    setImage(newImage);
    
    return true;
}

void ImageViewer::setImage(const QImage &newImage)
{
    image = newImage;
    image_label->setPixmap(QPixmap::fromImage(image));
    
    scaleFactor = 1.0;
}

void ImageViewer::on_click_btn_zoom_out()
{
    zoomOut();
}

void ImageViewer::on_click_btn_zoom_in()
{
    zoomIn();
}

void ImageViewer::on_click_btn_prev()
{
    emit signal_prev();
}

void ImageViewer::on_click_btn_next()
{
    emit signal_next();
}

void ImageViewer::zoomOut()
{
    scaleImage(0.8);
}

void ImageViewer::zoomIn()
{
    scaleImage(1.2);
}

void ImageViewer::scaleImage(double factor)
{
    Q_ASSERT(image_label->pixmap());
    scaleFactor *= factor;
    image_label->resize(scaleFactor * image_label->pixmap()->size());
}
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 

namespace Ui {
class MainWindow;
}

class ImageViewer;
class SearchFilter;

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private slots:
    void on_signal_next();
    void on_signal_prev();
    void on_signal_show_image(const QString& picture_path);
    
private:
    Ui::MainWindow *ui;
    
    QString dir_str;  //目录
    
    SearchFilter* m_widget_search_filter;
    ImageViewer* m_widget_image_viewr;
};

#endif // MAINWINDOW_H
mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
#include 
#include 
#include 
#include 
#include "searchfilter.h"
#include "imageviewer.h"
#include 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    dir_str = "D:\\UserData\\";
    
    QStringList filters;
    filters << "*.bmp";
    
    m_widget_search_filter = new SearchFilter();  //文件浏览
    m_widget_image_viewr = new ImageViewer();  //图片浏览
    
    m_widget_search_filter->setMinimumWidth(421);
    m_widget_search_filter->setMaximumWidth(421);
    
    QHBoxLayout* main_layout = new QHBoxLayout();
    main_layout->addWidget(m_widget_search_filter);
    main_layout->addWidget(m_widget_image_viewr);
    
    QWidget* main_widget = new QWidget(this);
    main_widget->setLayout(main_layout);
    
    this->setCentralWidget(main_widget);
    
    m_widget_search_filter->Init(dir_str, filters);
    
    connect(m_widget_search_filter, SIGNAL(signal_current_select_file(QString)), this, SLOT(on_signal_show_image(QString)));
    connect(m_widget_image_viewr, SIGNAL(signal_next()), this, SLOT(on_signal_next()));
    connect(m_widget_image_viewr, SIGNAL(signal_prev()), this, SLOT(on_signal_prev()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_signal_next()
{
    m_widget_search_filter->SetCurrentSelectFile_Next();
}

void MainWindow::on_signal_prev()
{
    m_widget_search_filter->SetCurrentSelectFile_Prev();
}

void MainWindow::on_signal_show_image(const QString &picture_path)
{
    m_widget_image_viewr->loadFile(picture_path);
}
虽然没有太多文字描述思路,但是代码中展示的思路还是比较清晰的,唯一一个地方比较难理解的就是使用正则表达式的那个地方

运行效果图

Qt 实现的简易本地图片浏览器_第1张图片

Qt 实现的简易本地图片浏览器_第2张图片

Qt 实现的简易本地图片浏览器_第3张图片

你可能感兴趣的:(QT)