非常好的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);
}
虽然没有太多文字描述思路,但是代码中展示的思路还是比较清晰的,唯一一个地方比较难理解的就是使用正则表达式的那个地方
运行效果图