Heim > Backend-Entwicklung > C++ > Hauptteil

Wie kann ich Dateikopier- und Umbenennungsvorgänge in Qt unterbrechen?

Susan Sarandon
Freigeben: 2024-11-13 15:33:02
Original
994 Leute haben es durchsucht

How can I interrupt file copy and rename operations in Qt?

Unterbrechen von Vorgängen zum Kopieren und Umbenennen von Dateien

In Situationen, in denen große Dateien übertragen werden müssen und Benutzer die Möglichkeit benötigen, den Vorgang abzubrechen, ist die Die von Qt angebotenen Standardmethoden copy() und rename() können einschränkend sein. Die Herausforderung besteht darin, diese Prozesse zu unterbrechen, ohne dass es zu erheblichem Leistungsaufwand oder Benutzerfrustration kommt.

Unterbrechungsunterstützung in Qt abfragen

Bei der Untersuchung der QFile-Dokumentation wird deutlich, dass Qt bietet keinen integrierten Mechanismus zum Unterbrechen von copy()- oder rename()-Vorgängen. Daher ist es notwendig, benutzerdefinierte Implementierungsstrategien in Betracht zu ziehen, um dieser Anforderung gerecht zu werden.

Benutzerdefinierte Implementierung für Kopierunterbrechung

Eine Möglichkeit besteht darin, einen nicht blockierenden Kopierhelfer zu erstellen um einen dedizierten Thread zu implementieren oder den Hauptthread zu nutzen. In beiden Fällen ist ein fragmentiertes Kopieren erforderlich, bei dem die Daten mithilfe eines Puffers in Blöcken übertragen werden. Durch die Verwendung eines Puffers ist es möglich, den Fortschritt des Vorgangs zu verfolgen und Abbruchanfragen von Benutzern zu berücksichtigen.

Die Kernschritte für die Implementierung eines benutzerdefinierten Kopierhilfsprogramms können wie folgt beschrieben werden:

  1. Erstellen Sie eine von QObject abgeleitete Klasse, um den Kopiervorgang abzuwickeln.
  2. Initialisieren Sie Eigenschaften für Quellpfad, Zielpfad, Puffergröße, Fortschritt und Bereinigung Abbruch.
  3. Definieren Sie einen begin()-Slot, um den Kopiervorgang zu starten, der das Öffnen von Quell- und Zieldateien und das Zuweisen eines Puffers für die Datenübertragung umfasst.
  4. Implementieren Sie einen step()-Slot , unter Verwendung von QMetaObject::invokeMethod() mit Qt::QueuedConnection, was die periodische Verarbeitung von Benutzerereignissen ermöglicht. Innerhalb dieses Slots:

    • Überprüfen Sie, ob der Kopiervorgang nicht abgebrochen wird.
    • Lesen und schreiben Sie Daten in Blöcken mithilfe von Quell- und Zieldateien.
    • Update-Fortschritt basierend auf Verhältnis von Position zu Dateigröße.
    • Rekursiv den Step()-Slot aufrufen, bis die gesamte Datei kopiert ist oder abgebrochen.
  5. Definieren Sie einen cancel()-Slot, damit Benutzer den Kopiervorgang unterbrechen und bei Bedarf die Zieldatei entfernen können.
  6. Verwenden Sie Signale, um interessierte Parteien über den Fortschritt zu informieren Änderungen und Vervollständigung (done()).

Beispiel Implementierung

Der folgende Codeausschnitt stellt eine Beispielimplementierung einer Kopierhilfsklasse dar:

class CopyHelper : public QObject {
    Q_OBJECT
    Q_PROPERTY(qreal progress READ progress WRITE setProgress NOTIFY progressChanged)
public:
    CopyHelper(QString sPath, QString dPath, quint64 bSize = 1024 * 1024) :
        isCancelled(false), bufferSize(bSize), prog(0.0), source(sPath), destination(dPath), position(0) { }
    ~CopyHelper() { free(buff); }

    qreal progress() const { return prog; }
    void setProgress(qreal p) {
        if (p != prog) {
            prog = p;
            emit progressChanged();
        }
    }

public slots:
    void begin() {
        if (!source.open(QIODevice::ReadOnly)) {
            qDebug() << "could not open source, aborting";
            emit done();
            return;
        }
        fileSize = source.size();
        if (!destination.open(QIODevice::WriteOnly)) {
            qDebug() << "could not open destination, aborting";
            // maybe check for overwriting and ask to proceed
            emit done();
            return;
        }
        if (!destination.resize(fileSize)) {
            qDebug() << "could not resize, aborting";
            emit done();
            return;
        }
        buff = (char*)malloc(bufferSize);
        if (!buff) {
            qDebug() << "could not allocate buffer, aborting";
            emit done();
            return;
        }
        QMetaObject::invokeMethod(this, "step", Qt::QueuedConnection);
        //timer.start();
    }
    void step() {
        if (!isCancelled) {
            if (position < fileSize) {
                quint64 chunk = fileSize - position;
                quint64 l = chunk > bufferSize ? bufferSize : chunk;
                source.read(buff, l);
                destination.write(buff, l);
                position += l;
                source.seek(position);
                destination.seek(position);
                setProgress((qreal)position / fileSize);
                //std::this_thread::sleep_for(std::chrono::milliseconds(100)); // for testing
                QMetaObject::invokeMethod(this, "step", Qt::QueuedConnection);
            } else {
                //qDebug() << timer.elapsed();
                emit done();
                return;
            }
        } else {
            if (!destination.remove()) qDebug() << "delete failed";
            emit done();
        }
    }
    void cancel() { isCancelled = true; }

signals:
    void progressChanged();
    void done();

private:
    bool isCancelled;
    quint64 bufferSize;
    qreal prog;
    QFile source, destination;
    quint64 fileSize, position;
    char * buff;
    //QElapsedTimer timer;
};
Nach dem Login kopieren

Fazit

Durch die Implementierung einer benutzerdefinierten Mit dem Kopierhelfer oder anhand des bereitgestellten Beispiels ist es möglich, einen nicht blockierenden Dateikopiervorgang zu erstellen, der von Benutzern unterbrochen werden kann. Dieser Ansatz ermöglicht reaktionsschnelle und benutzerfreundliche Dateiübertragungen und beseitigt die Frustrationen, die durch langwierige Vorgänge verursacht werden, die nicht abgebrochen werden können.

Das obige ist der detaillierte Inhalt vonWie kann ich Dateikopier- und Umbenennungsvorgänge in Qt unterbrechen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage