当我在单独的线程(Qt)中复制文件时,为什么我在使用QFileSystemModel的GUI中的树视图有时会冻结?

问题描述 投票:0回答:1

这是我的Model,它继承了QFileSystemModel

class MyFileSysModel : public QFileSystemModel
{
    Q_OBJECT
public:
    MyFileSysModel( QObject *parent = 0);
    Qt::ItemFlags  flags(const QModelIndex &index) const;
    bool dropMimeData(const QMimeData *data,
    Qt::DropActions supportedDropActions() const;
};

在MainWindow中,我创建了模型和初始化的树视图

 MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        model = new MyFileSysModel(this);
        model->setRootPath("/");
       ui->treeView->setModel(model);

         ui->treeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
         ui->treeView->setDragEnabled(true);
         ui->treeView->viewport()->setAcceptDrops(true);
         ui->treeView->setDropIndicatorShown(true);
         ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
         ui->treeView->setAcceptDrops(true);
         ui->treeView->setDefaultDropAction(Qt::MoveAction);
    }

当用户拖放文件时,它将复制到单独线程中的其他目录

 class MoveFilesTask : public QObject, QRunnable
    {
        Q_OBJECT
        void run()
        {
            QFile source("source_file_name");
            source.open(QIODevice::ReadOnly);
            QFile destination("some_destination");
            destination.open(QIODevice::WriteOnly);
            QByteArray buffer;
            int chunksize = 200;

            while(!(buffer = source.read(chunksize)).isEmpty())
            {
                destination.write(buffer);
            }
            destination.close();
            source.close();
        }
       void MoveFilesTask::runFilesTransfer(QString source, QString destination)
        {
           QThreadPool::globalInstance()->start(this);
        }
};

文件正在复制,但MainWindow中的GUI与我的树视图不能正常工作,有时会冻结和阻塞。我认为这是因为我的模型经常更新。如何解决这个问题并经常阻止更新?

c++ qt runnable file-copying qfilesystemmodel
1个回答
0
投票

QFileSystemModel列出后台线程上的目录,以避免阻止UI。但是,一旦它获得QFileSystemModelPrivate::_q_fileSystemChanged中的更新列表,它就会使用QFileInfoGatherer::getInfo()在主线程中获取文件的图标,QFileIconProvider::icon(QFileInfo)又调用qazxswpoi。

您应该知道模型没有使用不同的线程。他们正在使用主线程。

如果要使用Model,请在UI中使用加载动画(加载gif)来显示进度时间。

© www.soinside.com 2019 - 2024. All rights reserved.