-1

My code is about images. It can be open image, changing quality, resize, showing image size... For resize and change quaity, I use slider and when I change sliders values, image is read from buffer again and again. Because of this, freezing is happening in my program. So, to solve the problem I want to use QtConcurrent::run and QThread or QFuture. Actually I have no idea how can I use them and I would like to your help to solve my problem.

Here is my code. The functions are that to cause freezing:

void MainWindow::reprocess_image(int scale, int quality) {

     rescale_image(scale);
     requality_image(quality);
     show_pixmap();
}


void MainWindow::rescale_image(int scale) {
    int w = m_image->width();
    int h = m_image->height();
    int new_w = (w * scale)/100;
    int new_h = (h * scale)/100;

    ui->lbl_width->setText(QString::number(new_w));
    ui->lbl_height->setText(QString::number(new_h));

    m_pixmap = QPixmap::fromImage(
                m_image->scaled(new_w, new_h, Qt::KeepAspectRatio, Qt::FastTransformation));

    ui->lbl_scale->setText(QString::number(scale));

}

void MainWindow::requality_image(int quality) {
    QByteArray ba;
    QBuffer buffer(&ba);
    buffer.open(QIODevice::WriteOnly);
    m_pixmap.save(&buffer, "WEBP", quality);

    auto l_size_b = buffer.size();
    double l_size_kb = buffer.size() / 1024.00;
    ui->lbl_size->setText(QString::number(l_size_kb));

    QImage image;
    image.loadFromData(ba);
    m_pixmap = QPixmap::fromImage(image);

    ui->lbl_quality->setText(QString::number(quality));

    double comp_p = 100.0 * l_size_b / m_orig_size;

    if(comp_p>100) {
        ui->lbl_compression->setText(QString::number(comp_p));
        QLabel* m_label = ui->lbl_size;
        m_label->setStyleSheet("QLabel { background-color : red; color : black; }");
    }
    else if(comp_p<=100) {
        ui->lbl_compression->setText(QString::number(comp_p));
        QLabel* m_label = ui->lbl_size;
        m_label->setStyleSheet("QLabel { background-color : rgba(0,0,0,0%); color : black; }");
    }
}

void MainWindow::on_sld_quality_valueChanged(int value) {
    reprocess_image(ui->sld_scale->value(), value);
}

void MainWindow::on_sld_scale_valueChanged(int scale) {
    reprocess_image(scale, ui->sld_quality->value());
}

And this is my mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsPixmapItem>

QT_FORWARD_DECLARE_CLASS(QGraphicsScene)


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

protected:
    virtual void showEvent(QShowEvent *e) override;

private slots:
    void on_openButton_clicked();
    void on_sld_quality_valueChanged(int value);
    void on_sld_scale_valueChanged(int value);
    void on_saveButton_clicked();

private:
    void reprocess_image(int scale, int quality);
    void rescale_image(int);
    void requality_image(int);
    void show_pixmap();
    void change_size();

    Ui::MainWindow *ui;
    QPixmap m_pixmap;
    QImage  *m_image;
    qint64 m_orig_size;
    QGraphicsScene *m_scene;
};

#endif // MAINWINDOW_H

How can I integrate QtConcurrent::run(), QThread and QFuture to my code?

SurvivalMachine
  • 7,946
  • 15
  • 57
  • 87
doctor joe
  • 55
  • 1
  • 1
  • 6
  • 1
    What about http://doc.qt.io/qt-5/qtconcurrent-imagescaling-example.html? Maybe browse the documentation of Qt a bit, there are quite more examples covering this topic. – maxik Jul 01 '16 at 09:00
  • Agreed. This is a topic covered at length in articles and questions on SO. Please do some research and come back with a specific question. – jonspaceharper Jul 01 '16 at 09:37
  • Yes, I really doubt threading is the solution to this. Rather, there must be a better way to dynamically scale images. As proven by the fact that plenty of other programs manage to do it. – underscore_d Jul 01 '16 at 19:15

1 Answers1

0

The whole point of QtConcurrent::run is that you're not managing your own threads. So there's nothing to integrate. To get notified about when code submitted to QtConcurrent::run has finished you can use QFutureWatcher or emit a signal from the callable.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313