TransWikia.com

Копирование файлов/папок из одной папки в другую с использованием QListView

Stack Overflow на русском Asked by zhilenkov on August 30, 2021

При попытки взять ‘index’ и проверки на валидность получаю ‘false’.

QModelIndex QModelindex = ui->listView->currentIndex(); // пытаюсь получить индекс qDebug() << 
QModelindex.isValid();

Получаю false

Вот код конструктора :

sda1 = "/media/usbhd-sda1/";
sdb1 = "/media/usbhd-sdb1/";
model = new QFileSystemModel(this);
model->setFilter(QDir::AllEntries);
model->setRootPath(sda1);

MySort* proxy = new MySort();
proxy->setSourceModel(model); // сортировка работает 

int id = QFontDatabase::addApplicationFont("/usr/share/fonts/dejavu/DejaVuSansMono.ttf"); // установка шрифта 
QFont font = QFont(QFontDatabase::applicationFontFamilies(id).first());
font.setPointSize(11);

ui->listView->setModel(proxy);
ui->listView->setFont(font);
ui->listView->setGridSize( QSize( 64, 64 ) );
ui->listView->setIconSize( QSize( 64, 64 ) );
ui->listView->setUniformItemSizes( true );
ui->listView->setRootIndex(proxy->mapFromSource(model->index(sda1))); // авто-переход на usb накопитель

ui->listView_2->setModel(proxy);
ui->listView_2->setFont(font);
ui->listView_2->setGridSize( QSize( 64, 64) );
ui->listView_2->setIconSize( QSize( 64, 64 ) );
ui->listView_2->setUniformItemSizes( true );
proxy->sort(0, Qt::AscendingOrder);
connect(ui->listView_2, SIGNAL(clicked(QModelIndex)), this, SLOT(on_listView_clicked(QModelIndex)) ); // один слот(обработчик) для двух listView

void UsbConnect::on_pushButton_6_clicked()
{
    emit signalHideUsbConnect(); // закртие окна
}

void contentDifference(QDir &sDir, QDir &dDir, QFileInfoList &diffList)
{
    foreach(QFileInfo sInfo, sDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::DirsFirst)){
     bool fileExists = false;
      foreach(QFileInfo dInfo, dDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::DirsFirst)){
          if(sInfo.fileName() == dInfo.fileName()){
              if(sInfo.isDir() || sInfo.lastModified() <= dInfo.lastModified())
                  fileExists = true;
                  break;
          }
    }
    if(!fileExists)
       diffList.append(sInfo);
    if(sInfo.isFile())
        continue;
    if(fileExists){
        sDir.cd(sInfo.fileName());
        dDir.cd(sInfo.fileName());
        contentDifference(sDir, dDir, diffList);
        sDir.cdUp();
        dDir.cdUp();
    }
    else{
        sDir.cd(sInfo.fileName());
        recursiveContentList(sDir, diffList);
    }

    }
}

void recursiveContentList(QDir &dir, QFileInfoList &contentList)
{
    foreach(QFileInfo info, dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::DirsFirst)){
     contentList.append(info);
     if(info.isDir() && dir.cd(info.fileName())){
         recursiveContentList(dir, contentList);
         dir.cdUp();
     }
    }
}

void UsbConnect::on_listView_clicked(const QModelIndex &index) // переход по пути по одному клику
{
    // Получаем QModelIndex, соответствующий модели из прокси
    QListView* listView = (QListView*)sender(); // получается у нас один слот на два listView по этой причине создаю дополнительную модель listView и работаю уже с ней
    MySort* proxy = (MySort*)(listView->model());
    QFileInfo fileInfo =  model->fileInfo(proxy->mapToSource(index));
    if(fileInfo.fileName() == ".."){ // если нажали на папку с .. то переход на один уровень вверх
        QDir dir = fileInfo.dir();
        dir.cdUp();
        // Снова получаем значение из основной модели, используя посредник
        listView->setRootIndex( proxy->mapFromSource(model->index(dir.absolutePath())) );
    }
    else if(fileInfo.fileName() == "."){ // если нажали на папку с . то переход в корень
        listView->setRootIndex( proxy->mapFromSource(model->index("")) );
    }
    else if(fileInfo.isDir()){
       listView->setRootIndex(index);
    }
}

void UsbConnect::on_pushButton_clicked() // слот для копирования данных
{
   MySort* proxy = (MySort*)(ui->listView->model());
   MySort* proxy1 = (MySort*)(ui->listView_2->model());
   QModelIndex QModelindex = ui->listView->currentIndex(); // пытаюсь получить индекс
   qDebug() << QModelindex.isValid(); // получил false
   // Нужно получить пути от куда копировать и куда копировать
   QDir sDir = QDir(model->fileInfo(proxy->mapToSource(ui->listView->currentIndex())).dir()); // от куда копировать
   QDir dDir = QDir(model->fileInfo(proxy1->mapToSource(ui->listView_2->currentIndex())).dir()); // куда копировать
   qDebug() << sDir << dDir;
   /* получил
    *
    * QDir( "/media" , nameFilters = { * },  QDir::SortFlags( Name | IgnoreCase ) , QDir::Filters( Dirs|Files|Drives|AllEntries ) )
    * QDir( "/media" , nameFilters = { * },  QDir::SortFlags( Name | IgnoreCase ) , QDir::Filters( Dirs|Files|Drives|AllEntries ) )
    *
    а должны быть пути вида /media/usbhd-sda1 , /media/usbhd-sdb1
   */
   QFileInfoList diffList = QFileInfoList();
   contentDifference(sDir, dDir, diffList);
   foreach(QFileInfo diffInfo, diffList) {
   QString backupPath = diffInfo.filePath().replace(sDir.absolutePath(), dDir.absolutePath());
   if(diffInfo.isFile()){
   QFile::remove(backupPath);
   QFile::copy(diffInfo.absoluteFilePath(), backupPath);
   }
   if(diffInfo.isDir()){
       dDir.mkdir(backupPath);
   }
   }
   }

One Answer

Конструктор:

...

model = new QFileSystemModel(this);

//Показывать все содержимое папки
model->setFilter(QDir::AllEntries);

MySort* proxy = new MySort();
proxy->setSourceModel(model);
proxy->sort(0, Qt::AscendingOrder);

ui->listView->setModel(proxy);

// Режим множественного выбора элементов
ui->listView->setSelectionMode(QAbstractItemView::MultiSelection);
// Корневая директория
model->setRootPath( sda1 );
// Отображаем корневую диреторию
ui->listView->setRootIndex( proxy->mapFromSource( model->index(model->rootPath())) );

ui->listView_2->setModel(proxy);

// Режим множественного выбора элементов
ui->listView->setSelectionMode(QAbstractItemView::SingleSelection);
model->setRootPath( sdb1 );
ui->listView_2->setRootIndex( proxy->mapFromSource( model->index(model->rootPath())) );

// Устанавливаем текущий индекс в списке выбора папки назначения
ui->listView_2->setCurrentIndex( ui->listView_2->rootIndex() );

...

Слот нажатия на кнопку "Скопировать":

void UsbConnect::on_pushButton_clicked()
{
    MySort* proxy = qobject_cast<MySort*>(ui->listView->model());

    // Получаем индекс директории назначения
    QModelIndex destinationIndex = ui->listView_2->currentIndex();

    // Если папка выбрана, то
    if( destinationIndex.isValid() ) {
        // Получаем QFileInfo директории назначения
        QFileInfo destinationFileInfo = model->fileInfo( proxy->mapToSource(destinationIndex) );

        // Получаем список выбранных файлов/директорий для копирования
        QModelIndexList list = ui->listView->selectionModel()->selectedIndexes();
        QListIterator<QModelIndex> iter(list);
        while( iter.hasNext() ) {
            QModelIndex sourceIndex = proxy->mapToSource(iter.next());
            QFileInfo fileInfo = model->fileInfo( sourceIndex );
            
            // Копируем из старой папки в новую с сохранением имен папок и файлов
            QFile::copy( fileInfo.filePath(), destinationFileInfo.filePath() + QDir::separator() + fileInfo.fileName());
        }
    }
}

Correct answer by Alexander Chernin on August 30, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP