飞凌嵌入式
直播中

fsdzdzy

10年用户 260经验值
擅长:嵌入式技术 控制/MCU opencv
私信 关注
[技术]

【飞凌RK3568开发板试用体验】5-Qt开发一个相册浏览器

本篇继续来实现一个Qt相册浏览器软件,可以实现OK3568-C板子中图片的查看,方便后面制作相机拍照功能后,可以查看拍出的照片,先来看下最终的效果:

本篇的Qt代码从野火开发板的例程中移植修改而来,下面分析下程序的代码结构。

1 相册浏览器开发总体结构

整个Qt相册浏览器项目的代码结构如下:

  • 主代码中是相册浏览器相关的代码,包括:
    • 相册浏览器主界面
    • 图片详情视图界面:可以实现图片的查看,放大、缩小,旋转,切换到上一张下一张,幻灯片播放
    • 图片列表视图界面:可以实现图片缩略图的列表预览
  • Ui代码中使用一些Qt的基本功能,包括:
    • 一个Qt界面基类
    • 图标按钮显示类
    • 工具类
    • 页面列表类
  • Skin中是一些图片资源和字体/皮肤定义
  • 最后是编译的中间文件和编译结果存储的目录

下面分类介绍了程序的主要代码实现。

2 软件开发

首先是整体的主界面部分,包括相册浏览器标题的设置和图片列表视图的初始化,然后使用一个垂直布局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);
}

初始化图片列表后,还要连接对应的槽函数,在点击对应的图片后,要切换到对应图片的详情界面。

2.1 图片预览列表

图片预览列表视图如下,在进入相册浏览器功能后,会显示各个图片的缩略图,左右可以滑动到下一页查看更多的图片,点击对应的图片,可以跳转到图片的详情页。

2.1.1 读取图片文件

通过读取指定目录下的文件,查找类型为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);
    }
}

2.1.2 图片列表界面

图片列表的具体实现,主要是在对应的矩形位置,通过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();
}

2.2 图片详情页

图片详情页,可以查看图片的详细信息,左右切换图片,放大缩小图片,旋转图片,以及幻灯片播放所有图片。

2.2.1 图片详情页布局

图片详情页,主要包括:

  • 顶部的图片名称
  • 中间的图片展示
  • 底部的图片操作按钮
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()));
}

2.2.2 图片详情页底部操作按钮

图片详情页底部操作按钮,包括:

  • 放大、缩小按钮
  • 幻灯片播放按钮
  • 顺时针旋转、逆时针旋转按钮
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)));
}

图片缩小显示结果:

图片旋转显示结果:

3 交叉编译与测试

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文件夹,里面放入若干个图片文件,然后就可以测试了:

实测效果见文末视频,整体图片流程操作流畅。

4 总结

本篇介绍了在OK3568-C开发板上实现一个相册浏览器的测评过程,首先使用Qt编写相册浏览器的代码,然后在Ubuntu中,使用搭建好的交叉编译环境进行代码编译,最后把编译出的可执行文件放到板子中进行实际测试。

演示视频:

Qt相册浏览器演示

更多回帖

发帖
×
20
完善资料,
赚取积分