Search code examples
qtqimageqscrollarea

Qscrollarea images disappeard immidiately


I have written the code below in order to show images which exist in a special directory on a scroll area. but when I trigger the actionOpen, images will be disappeared immediately. how can I make the Images stable?

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
ui->setupUi(this);

layout = ui->verticalLayout;
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::on_actionOpen_triggered()
{


QString directory = QFileDialog::getExistingDirectory(this,
                                                      tr("OpenDirectory"),
                                                      QDir::homePath(),
                                                      QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);

int nrows = 1;
int ncols = 1;
HorizontalScrollArea scroll(nrows, ncols);
layout->addWidget(&scroll);

    QDir dir(directory);
    dir.setNameFilters({"*.png", "*.jpg"});
    for(const QFileInfo & finfo: dir.entryInfoList()){

        QMessageBox::information(this,"log",finfo.absolutePath());
        int column = scroll.columnCount();
        for(int row=0; row < nrows; row++){
            QPixmap pic(finfo.absoluteFilePath());
            QLabel *label = new QLabel(QString("label: %1 %2")
                                       .arg(row)
                                       .arg(column));
            label->setFrameShape(QFrame::Box);
            label->setAlignment(Qt::AlignCenter);
            label->setPixmap(pic.scaled(500,600,Qt::KeepAspectRatio));
            scroll.addWidget(label, row, column);
        }
    }
  }

and horizontasScrollarea.h

class HorizontalScrollArea : public QScrollArea
{
QWidget *contentWidget;
QGridLayout *grid;
int nRows;
int nColumns;
public:
HorizontalScrollArea(int rows, int cols, QWidget *parent = Q_NULLPTR)
    :QScrollArea(parent), nRows(rows), nColumns(cols)
{
    setWidgetResizable(true);
    contentWidget = new QWidget(this);
    setWidget(contentWidget);
    grid = new QGridLayout(contentWidget);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

void addWidget(QWidget *w, int row, int col){
    grid->addWidget(w, row, col);
    adaptSize();
}

int columnCount() const{
    if(grid->count() == 0){
        return 0;
    }
    return grid->columnCount();
}

private:
void adaptSize(){
    if(columnCount() >= nColumns ){
        int w = 1.0*(width() - grid->horizontalSpacing()*(nColumns+1.6))/nColumns;
        int wCorrected = w*columnCount() + grid->horizontalSpacing()*(columnCount()+2);
        contentWidget->setFixedWidth(wCorrected);
    }
    contentWidget->setFixedHeight(viewport()->height());
}
protected:
void resizeEvent(QResizeEvent *event){
    QScrollArea::resizeEvent(event);
    adaptSize();
}
};

in order to see the images, I have placed an information button which will be executed whenever a picture appears.


Solution

  • A variable that is created within a method is eliminated when the method is finished executing, in your case scroll is, the solution is to use a pointer.

    QString directory = QFileDialog::getExistingDirectory(this,
                                                          tr("OpenDirectory"),
                                                          QDir::homePath(),
                                                          QFileDialog::ShowDirsOnly| QFileDialog::DontResolveSymlinks);
    
    int nrows = 1;
    int ncols = 1;
    HorizontalScrollArea *scroll = new HorizontalScrollArea(nrows, ncols);
    layout->addWidget(scroll);
    
    QDir dir(directory);
    dir.setNameFilters({"*.png", "*.jpg"});
    for(const QFileInfo & finfo: dir.entryInfoList()){
    
        QMessageBox::information(this,"log",finfo.absolutePath());
        int column = scroll->columnCount();
        for(int row=0; row < nrows; row++){
            QPixmap pic(finfo.absoluteFilePath());
            QLabel *label = new QLabel(QString("label: %1 %2")
                                       .arg(row)
                                       .arg(column));
            label->setFrameShape(QFrame::Box);
            label->setAlignment(Qt::AlignCenter);
            label->setPixmap(pic.scaled(500,600,Qt::KeepAspectRatio));
            scroll->addWidget(label, row, column);
        }
    }