首页 > 解决方案 > 显示用户选择的源目录中的图像

问题描述

我有一个 Qt 应用程序,用户在其中选择包含图像(.pgm 文件)(任意数量)的源目录。在 UI 中,我创建了一个显示区域(QGroupBox),它有 2 个 QGraphicsview,一次显示 2 个图像。

用户界面图片:

当前图形用户界面

继续,我想为所有图像创建 QGraphicsViews 小部件,并一次显示 2 个。右侧会有一个滚动条。当用户向下拖动滚动条时,其他 QGraphicsView 小部件应该对具有不同图像的用户可见。我如何在 C++ 中使用 Qt 来做到这一点?

PS:当单击加载图像按钮时,我可以使用 QGraphicsView Widget 在显示区域中显示两个图像。

#include "ui_DataViewerPage.h"

#include <iostream>

#include <QGraphicsScene>
#include <QPixmap>
#include <QThread>
#include <QSettings>

#include "DataWorker.h"

namespace Ui
{
    class DataViewerPage;
}
 // This is the main UI thread header and cpp file
class DataViewerPage : public QWidget
{
    Q_OBJECT
public:
    DataViewerPage(QWidget* parent = nullptr);
    virtual ~DataViewerPage();

public slots:
    void on_loadButton_clicked();

    void startWorker();
    void stopWorker();

    void displayImage(QString fileName);
signals:
    void startLoadingImages();

private:
    Ui::DataViewerPage* ui;
    DataWorker* worker;
    QSettings settings;

    // Worker thread handles data processing away from ui thread
    QThread workerThread;
    QSharedPointer<QGraphicsScene> ptr_scene;
    QSharedPointer<QGraphicsScene> ptr_scene2;
    int currentDisplayNum;
};

#include "DataViewerPage.h"

DataViewerPage::DataViewerPage(QWidget* parent)
    : QWidget(parent), worker(nullptr), ui(new Ui::DataViewerPage)
{
    ui->setupUi(this);
    ui->Display->setVisible(true);
    ptr_scene = QSharedPointer<QGraphicsScene>(new QGraphicsScene(this));
    ptr_scene2 = QSharedPointer<QGraphicsScene>(new QGraphicsScene(this));
}

DataViewerPage::~DataViewerPage()
{
    workerThread.quit();
    workerThread.wait();
    workerThread.terminate();
    if (worker)
    {
        delete worker;
    }

    delete ui;
}

void DataViewerPage::on_loadButton_clicked()
{
    ui->Display->setVisible(true);
    ui->loadButton->setDisabled(true);
    emit startLoadingImages();
}


void DataViewerPage::stopWorker()
{
    workerThread.quit();
    workerThread.wait();
    workerThread.terminate();

    if (worker)
    {
        delete worker;
        worker = nullptr;
    }
}

void DataViewerPage::startWorker()
{
    stopWorker();
    worker = new DataWorker();
    worker->moveToThread(&workerThread);

    connect(this, &DataViewerPage::startLoadingImages, worker, &DataWorker::startLoadingImages);
    connect(worker, &DataWorker::displayImage, this, &DataViewerPage::displayImage);

    workerThread.start();
    currentDisplayNum = 0;
}

void DataViewerPage::displayImage(QString fileName)
{
    QPixmap pixelMap(fileName.toStdString().c_str()); // <- path to image file
    switch (currentDisplayNum)
    {
    case 0:
        ptr_scene->addPixmap(pixelMap);
        ui->img1->setScene(ptr_scene.get());
        break;
    case 1:
        ptr_scene2->addPixmap(pixelMap);
        ui->img2->setScene(ptr_scene2.get());
        break;
    default:
        break;
    }
    currentDisplayNum++;
}

// This is the worker thread header and cpp file. 
#pragma once
#include <QThread>
#include <QSettings>
#include <filesystem>

class DataWorker : public QObject
{
    Q_OBJECT
public:
    DataWorker();
    ~DataWorker();

public slots:
    void startLoadingImages();
signals:
    void displayImage(QString fileName);

private:
    QSettings settings;
    std::string path;
};

#include "DataWorker.h"
#include <iostream>
#include <QImage>

DataWorker::DataWorker()
{
    path = settings.value("dataDir").toString().toStdString();
}

DataWorker::~DataWorker()
{
}

void DataWorker::startLoadingImages()
{
    std::cout << "startloadingImages called..." << std::endl;
    int iCount = 0;
    for (const auto& entry : std::filesystem::directory_iterator(path))
    {
        QString imgPath = QString::fromStdString(entry.path().string());
        emit displayImage(imgPath);
        iCount++;
        if(iCount > 1)
            break; // Right now do it for two only.......
    }
}

标签: c++qtuser-interface

解决方案


推荐阅读