本篇继续来实现一个Qt相册浏览器软件,可以实现OK3568-C板子中图片的查看,方便后面制作相机拍照功能后,可以查看拍出的照片,先来看下最终的效果:
本篇的Qt代码从野火开发板的例程中移植修改而来,下面分析下程序的代码结构。
整个Qt相册浏览器项目的代码结构如下:
下面分类介绍了程序的主要代码实现。
首先是整体的主界面部分,包括相册浏览器标题的设置和图片列表视图的初始化,然后使用一个垂直布局QVBoxLayout来进行整体布局。
void PhotosView::InitWidget()
{
//相册浏览器标题
QtWidgetTitleBar *widgetTitle = new QtWidgetTitleBar(this);
widgetTitle->SetScalSize(Skin::m_nScreenWidth, 60);
widgetTitle->SetBackground(QColor("#f0f0f0"));
widgetTitle->SetTitle(tr("相册"), "#333333", 25);
connect(widgetTitle, SIGNAL(signalBackHome()), this, SIGNAL(signalBackHome()));
//图片列表视图
m_photoListView = new PhotoListView(this);
m_photoListView->SetBackground(QColor("#ffffff"));
connect(m_photoListView, SIGNAL(currentItemClicked(QtPageListWidgetItem *)), this, SLOT(SltCurrentItemClicked(QtPageListWidgetItem *)));
QVBoxLayout *verLayout = new QVBoxLayout(this);
verLayout->setContentsMargins(0, 0, 0, 0);
verLayout->setSpacing(0);
verLayout->addWidget(widgetTitle, 1);
verLayout->addWidget(m_photoListView, 7);
}
初始化图片列表后,还要连接对应的槽函数,在点击对应的图片后,要切换到对应图片的详情界面。
图片预览列表视图如下,在进入相册浏览器功能后,会显示各个图片的缩略图,左右可以滑动到下一页查看更多的图片,点击对应的图片,可以跳转到图片的详情页。
通过读取指定目录下的文件,查找类型为jpg、png、bmp的图片文件,构造图片列表。
void PhotosView::SltLoadPhotos()
{
m_listItems.clear();
for (auto strDirPath : m_strDirPath)
{
QDir dir(strDirPath);
dir.setFilter(QDir::Files | QDir::NoSymLinks);
QFileInfoList list = dir.entryInfoList(QStringList() << "*.jpg"
<< "*.png"
<< "*.bmp");
for (int i = 0; i < list.size(); ++i)
{
QFileInfo fileInfo = list.at(i);
QPixmap pixmap(fileInfo.absoluteFilePath());
if (pixmap.width() > pixmap.height())
{
pixmap = pixmap.scaledToHeight(200);
}
else
{
pixmap = pixmap.scaledToWidth(200);
}
pixmap = pixmap.copy(0, 0, 200, 200);
m_listItems.insert(i, new QtPageListWidgetItem(i, fileInfo.absoluteFilePath(), pixmap));
}
m_photoListView->SetItems(m_listItems);
}
}
图片列表的具体实现,主要是在对应的矩形位置,通过drawPixmap函数来显示各个图片的缩略图:
void PhotoListView::drawItemInfo(QPainter *painter, QtPageListWidgetItem *item)
{
painter->save();
if (item->m_pixmapIcon.isNull())
{
QFont font = painter->font();
font.setPixelSize(32);
painter->setFont(font);
painter->setPen("#ff0000");
painter->drawText(item->m_rect, Qt::AlignCenter, tr("图片已损坏"));
}
else
{
painter->drawPixmap(item->m_rect, item->m_pixmapIcon);
painter->setPen(QPen(QColor("#ffffff"), 2));
painter->setBrush(Qt::NoBrush);
painter->drawRect(item->m_rect);
}
painter->restore();
}
图片详情页,可以查看图片的详细信息,左右切换图片,放大缩小图片,旋转图片,以及幻灯片播放所有图片。
图片详情页,主要包括:
ImageViewer::ImageViewer(QWidget *parent) : QWidget(parent)
{
this->setAttribute(Qt::WA_DeleteOnClose);
m_bPressed = false;
m_nScaleFactor = 100;
m_nRotate = 0;
m_bToolBtnShow = false;
m_btnPrev = new QPushButton(this);
connect(m_btnPrev, SIGNAL(clicked(bool)), this, SLOT(SltShowPrevImage()));
m_btnPrev->setVisible(false);
m_btnPrev->setStyleSheet(QString("QPushButton {border-image: url(:/images/photos/toolbar/ic_left.png);}"
"QPushButton:pressed {border-image: url(:/images/photos/toolbar/ic_left_pressed.png);}"
"QPushButton:!enabled {border-image: url(:/images/photos/toolbar/ic_left_pressed.png);}"));
m_btnNext = new QPushButton(this);
connect(m_btnNext, SIGNAL(clicked(bool)), this, SLOT(SltShowNextImage()));
m_btnNext->setVisible(false);
m_btnNext->setStyleSheet(QString("QPushButton {border-image: url(:/images/photos/toolbar/ic_right.png);}"
"QPushButton:pressed {border-image: url(:/images/photos/toolbar/ic_right_pressed.png);}"
"QPushButton:!enabled {border-image: url(:/images/photos/toolbar/ic_right_pressed.png);}"));
m_titleBar = new TitleBarWidget(this);
connect(m_titleBar, SIGNAL(signalBack()), this, SLOT(close()));
m_bottomBar = new BottomBarWidget(this);
connect(m_bottomBar, SIGNAL(buttonClicked(int)), this, SLOT(SltToolButtonClicked(int)));
connect(m_bottomBar, SIGNAL(signalPlay(bool)), this, SLOT(SltAutoPlay(bool)));
m_opacity = 1.0;
m_timer = new QTimer(this);
m_timer->setInterval(50);
connect(m_timer, SIGNAL(timeout()), this, SLOT(SltSetOpacity()));
m_timerSlide = new QTimer(this);
m_timerSlide->setInterval(3000);
connect(m_timerSlide, SIGNAL(timeout()), this, SLOT(SltPlaySlide()));
}
图片详情页底部操作按钮,包括:
void BottomBarWidget::InitWidget()
{
QButtonGroup *btnGroup = new QButtonGroup(this);
QHBoxLayout *horLayout = new QHBoxLayout(this);
horLayout->setContentsMargins(10, 10, 10, 10);
horLayout->setSpacing(84);
horLayout->addStretch();
QPushButton *btnPlus = new QPushButton(this);
btnPlus->setStyleSheet(QString("QPushButton {border-image: url(:/images/photos/toolbar/ic_add.png);}"
"QPushButton:pressed {border-image: url(:/images/photos/toolbar/ic_add_press.png);}"));
btnGroup->addButton(btnPlus, 1);
horLayout->addWidget(btnPlus);
QPushButton *btnMins = new QPushButton(this);
btnMins->setStyleSheet(QString("QPushButton {border-image: url(:/images/photos/toolbar/ic_mins.png);}"
"QPushButton:pressed {border-image: url(:/images/photos/toolbar/ic_mins_press.png);}"));
btnGroup->addButton(btnMins, 2);
horLayout->addWidget(btnMins);
m_btnPlay = new QPushButton(this);
connect(m_btnPlay, SIGNAL(clicked(bool)), this, SIGNAL(signalPlay(bool)));
m_btnPlay->setCheckable(true);
m_btnPlay->setChecked(false);
m_btnPlay->setStyleSheet(QString("QPushButton {border-image: url(:/images/photos/toolbar/play.png);}"
"QPushButton:checked {border-image: url(:/images/photos/toolbar/pause.png);}"));
horLayout->addWidget(m_btnPlay);
QPushButton *btnLeftRotate = new QPushButton(this);
btnLeftRotate->setStyleSheet(QString("QPushButton {border-image: url(:/images/photos/toolbar/left_rotate.png);}"
"QPushButton:pressed {border-image: url(:/images/photos/toolbar/left_rotate_pressed.png);}"));
btnGroup->addButton(btnLeftRotate, 4);
horLayout->addWidget(btnLeftRotate);
QPushButton *btnRightRotate = new QPushButton(this);
btnRightRotate->setStyleSheet(QString("QPushButton {border-image: url(:/images/photos/toolbar/right_rotate.png);}"
"QPushButton:pressed {border-image: url(:/images/photos/toolbar/right_rotate_pressed.png);}"));
btnGroup->addButton(btnRightRotate, 5);
horLayout->addWidget(btnRightRotate);
horLayout->addStretch();
this->setStyleSheet(QString("QPushButton {min-width: 30px; min-height: 30px;}"));
connect(btnGroup, SIGNAL(buttonClicked(int)), this, SIGNAL(buttonClicked(int)));
}
图片缩小显示结果:
图片旋转显示结果:
Qt程序编写好后,通过交叉编译,来测试相册浏览器在OK3568-C板子上的播放效果。
使用编译音乐播放器时编写my3568build.sh的编译脚本编译即可,无需修改:
#! /bin/bash
mkdir -p build
cd build
export PATH=/home/xxpcb/myTest/OK3568/sourcecode/OK3568-linux-source/buildroot/output/OK3568/host/bin:$PATH
qmake .. && make
执行该脚本即可编译:
./my3568build.sh
将编译成功的可执行文件PhotosView复制到OK3568-C板子中,然后在其同目录下创建一个photos文件夹,里面放入若干个图片文件,然后就可以测试了:
实测效果见文末视频,整体图片流程操作流畅。
本篇介绍了在OK3568-C开发板上实现一个相册浏览器的测评过程,首先使用Qt编写相册浏览器的代码,然后在Ubuntu中,使用搭建好的交叉编译环境进行代码编译,最后把编译出的可执行文件放到板子中进行实际测试。
更多回帖