我如何使用QtConcurrent::Run和QThread

How can I use QtConcurrent::Run and QThread?

本文关键字:Run QThread QtConcurrent 何使用      更新时间:2023-10-16

我的代码是关于图像的。它可以打开图像,改变质量,调整大小,显示图像大小…对于调整大小和更改质量,我使用滑块,当我更改滑块值时,图像会一次又一次地从缓冲区读取。因此,在我的程序中发生了冻结。为了解决这个问题,我想用QtConcurrent::runQThread或者QFuture。实际上我不知道如何使用它们,我希望你能帮助我解决我的问题。

这是我的代码。导致冻结的函数是:
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());
}

这是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

我如何将QtConcurrent::run(), QThreadQFuture集成到我的代码中?

QtConcurrent::run的重点在于您不是管理自己的线程。所以没有积分。要获得关于提交给QtConcurrent::run的代码何时完成的通知,您可以使用QFutureWatcher或从可调用对象发出信号。