2016-07-01 32 views
-1

Mein Code ist über Bilder. Es kann geöffnetes Bild sein, Qualität ändern, Größe ändern, Bildgröße anzeigen ... Für die Größenänderung und Änderung der Quaität verwende ich den Schieberegler und wenn ich Schiebereglerwerte ändere, wird das Bild immer wieder aus dem Puffer gelesen. Aus diesem Grund geschieht das Einfrieren in meinem Programm. Also, um das Problem zu lösen, möchte ich QtConcurrent::run und QThread oder QFuture verwenden. Eigentlich habe ich keine Ahnung, wie ich sie benutzen kann und ich möchte mit deiner Hilfe mein Problem lösen.Wie kann ich QtConcurrent :: Run und QThread verwenden?

Hier ist mein Code. Die Funktionen sind, dass ein Einfrieren verursachen:

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()); 
} 

Und das ist mein 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 

Wie kann ich QtConcurrent::run(), QThread und QFuture zu meinen Code zu integrieren?

+1

Was ist mit http://doc.qt.io/qt-5/qtconcurrent-imagescaling-example.html? Schauen Sie sich die Dokumentation von Qt ein wenig an, es gibt noch mehr Beispiele zu diesem Thema. – maxik

+0

Einverstanden. Dies ist ein Thema, das ausführlich in Artikeln und Fragen zu SO behandelt wird. Bitte recherchieren Sie und kommen Sie mit einer spezifischen Frage zurück. –

+0

Ja, ich glaube wirklich, Threading ist die Lösung dafür. Vielmehr muss es eine bessere Möglichkeit geben, Bilder dynamisch zu skalieren. Dies wird durch die Tatsache bewiesen, dass viele andere Programme es schaffen. –

Antwort

0

Der springende Punkt von QtConcurrent::run ist, dass Sie nicht verwalten Ihre eigenen Threads sind. Es gibt also nichts zu integrieren. Um benachrichtigt zu werden, wann der an QtConcurrent::run übermittelte Code beendet wurde, können Sie QFutureWatcher verwenden oder ein Signal von der aufrufbaren Nachricht ausgeben.