通常用看圖軟體挑照片時,都不會只看一張圖吧?我們一定希望可以快速瀏覽過目錄裡的所有圖片。
所以今天我們來實現看圖軟體的另一個重要功能:上一張與下一張。
要顯示「上一張」或「下一張」的圖片,最關鍵的一點,就是要知道目錄下有哪些圖片,有一張圖片檔案清單。
要怎麼拿到這個清單呢?Qt 提供了一些便捷的方法,可以獲取目錄下的檔案清單。
最簡單的作法是透過 QDir 目錄物件。請看以下的範例程式,功用是印出目錄C:/tmp下的所有圖片,程式碼相當精簡,讀起來應該不難:
QDir dir("C:/temp/"); // 建立 QDir 物件,建構子傳入目錄路徑
// 用副檔名篩選檔案
QStringList nameFilter{"*.jpg", "*.png"};
// 呼叫entryInfoList()獲取檔案清單
QFileInfoList list = dir.entryInfoList(nameFilter);
// 迴圈走訪所有檔案並印出檔名
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
qDebug() << QString("%1").arg(fileInfo.fileName());
}
請打開昨天的專案,我們開始寫程式:
我們到 MainWindow 裡面新加兩個成員函數 prevImage()
和 nextImage()
,還有兩個成員變數 QDir m_currentDir
, m_currentImageName
。
class MainWindow : public QMainWindow
{
...
void prevImage();
void nextImage();
private:
QDir m_currentDir; // 表示當前圖片所在的目錄
QString m_currentImageName; // 當前圖片的路徑
...
}
接著到 loadImage 方法的最下方,藉著讀取圖片時創建的 fileInfo 變數,可以順便抓到當前目錄,以及圖片的檔名,我們把這兩樣資訊放到成員變數保存起來,接下來會用到:
void MainWindow::loadImage(const QString& fileName)
{
...
QFileInfo fileInfo(fileName);
...
m_currentImageName = fileInfo.fileName(); // 抓取當前圖片的檔名
m_currentDir = fileInfo.dir(); // 抓取圖片所在的當前目錄!
}
緊接著,我們就著手實現「上一張」的功能。
當使用者要求顯示「上一張圖片」時,我們先從 m_currentDir.entryInfoList() 獲取當前目錄下圖片檔案的清單。接著去定位目前圖片在這個清單中的位置(currentImgIndex),把位置減一,就知道「前一張圖片」是誰囉!
void MainWindow::prevImage()
{
QStringList nameFilter{"*.jpg", "*.png"};
QFileInfoList files = m_currentDir.entryInfoList(nameFilter);
int currentImgIndex = -1;
for (int i = 0; i < files.size(); ++i)
{
if (files[i].fileName() == m_currentImageName)
{
currentImgIndex = i;
break;
}
}
int prevImgIndex = currentImgIndex - 1;
if (prevImgIndex < 0)
return;
loadImage(files[prevImgIndex].absoluteFilePath());
}
你可以用相似的邏輯實現「下一張」這個功能嗎?這個課題就留給讀者囉。
最後利用昨天講解的選單列功能,增加「瀏覽」-> 「上一張」「下一張」選單項目:
QMenu* viewMenu = menuBar->addMenu("瀏覽");
QAction* prevImgAction = new QAction("上一張");
QAction* nextImgAction = new QAction("下一張");
viewMenu->addAction(prevImgAction);
viewMenu->addAction(nextImgAction);
connect(prevImgAction, &QAction::triggered,
this, &MainWindow::prevImage);
connect(nextImgAction, &QAction::triggered,
this, &MainWindow::nextImage);
透過選單操作,就可以用自由的瀏覽目錄內的每一張圖片囉!