Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Rename a lot of files by QFile and QFileSystemModel
QtWS25 Last Chance

Rename a lot of files by QFile and QFileSystemModel

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 4.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    stereomatching
    wrote on last edited by
    #1

    my pc : lenovo G770
    compiler : minGW 4.6.2(32bits)
    Qt version : 4.8.1

    I would like to show the files by QTableView and select the files
    I want to rename, but when the files are more than 1000, the speed
    would be pretty slow, the GUI will stall at there too.

    [code]
    int manyFiles(QApplication &app)
    {
    QFileSystemModel model;
    QString const rootPath = "E:/file_test/very big";

    QTableView view;
    view.setModel(&model);
    view.setRootIndex(model.setRootPath(rootPath));
    
    view.show();
    //....select the data you want to rename from the view
    //let us assume I select 8000 of jpg files
    
    //don't know how to rename the file by QFileSystemModel, so I use QFile instead
    QDir::setCurrent(rootPath);
    for(int i = 0; i != 8000; ++i)
    {
      QFile file(rootPath + "/jjj" + QString::number(i) + ".jpg");
      //qDebug() <<file.isOpen();
      file.rename("kkk" + QString::number(i) + ".jpg");
    }    
    
    //the program will stall
    
    app.exec();
    

    }
    [/code]

    I find out that the view and the model will update after I rename the file
    Could I ask the model and view don't update automatically before I rename all of the files?

    Thanks

    1 Reply Last reply
    0
    • L Offline
      L Offline
      lgeyer
      wrote on last edited by
      #2

      You can modify the model using setData() as soon as you've set readOnly to false.

      I'm not quite sure if there is a convenient way of disabling view updates, but have you tried disabling the view (or its updates), removing the model and/or just blocking signals?

      1 Reply Last reply
      0
      • S Offline
        S Offline
        stereomatching
        wrote on last edited by
        #3

        bq. disabling the view

        I tried to change the rootIndex of the view, but the model
        still update automatically

        bq. removing the model

        I removed the model but it would crash(by delete)
        sometimes(some sort of undefined behavior?).

        bq. blocking signals

        I am searching the document but can't find a way to do it, could
        you show me how?

        I found a suggestion book-- "advanced Qt
        programming" from amazon, looks like this book spend several
        hundreds pages to explain how to make a good use of Model/View.

        Since rename would involve I/O, I would not expect it could be
        some fast process, but If I could prevent the model to update
        automatically, it should make the GUI smoother.

        Thanks a lot

        1 Reply Last reply
        0
        • S Offline
          S Offline
          stereomatching
          wrote on last edited by
          #4

          I block the signal of QTableView and QFileSystemModel, it really stop to update the view
          and model(looks like), but the GUI still stall at there, multi-thread can't solve the problem
          at will emit a warning message like "it is unsafe to use QPixmap in other
          thread", so I better don't use it.

          [code]
          int manyFiles(QApplication &app)
          {
          QFileSystemModel model;
          QString const rootPath = "E:/file_test/very big";

          QTableView view;
          view.setModel(&model);
          view.setRootIndex(model.setRootPath(rootPath));
          
          view.show();
          //....select the data you want to rename from the view
          //let us assume I select 8000 of jpg files
          
          //don't know how to rename the file by QFileSystemModel, so I use QFile instead
          QDir::setCurrent(rootPath);
          model.blockSignals(true);
          view.blockSignals(true);
          for(int i = 0; i != 8000; ++i)
          {
            QFile file&#40;rootPath + "/kkk" + QString::number(i&#41; + ".jpg");
            file.rename("jjj" + QString::number(i) + ".jpg");
          }
          
          //the program will stall
          qDebug() << "finish";
          
          app.exec();
          

          }
          [/code]

          I added a progress bar to show the progress, but the progress bar also stall
          How could I make the UI become alive when the files being rename?Thanks

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            The problem is your tight loop in the main GUI thread in lines 18-22. I think this is typically a job for a worker thread. You should look into creating a class that subclasses QRunnable, like this:

            @
            class FileRenameRunnable: public QRunnable
            {
            FileRenameRunnable(QString fromPath, QString toPath)
            : m_fromPath(fromPath), m_toPath(toPath)
            {
            setAutoDelete(true);
            }

            virtual void run()
            {
                QFile file&#40;m_fromPath&#41;;
                file.rename(m_toPath);
            }
            

            private:
            QString m_fromPath;
            QString m_toPath;
            }

            //instead of your loop
            //...
            for(int i = 0; i != 8000; ++i)
            {
            QThreadPool::globalInstance()->start(new FileRenameRunnable(
            rootPath + "/kkk" + QString::number(i) + ".jpg",
            rootPath + "/kkk" + QString::number(i) + ".jpg"));
            }
            @

            Or look into other alternatives like basic QThreads or QtConcurrent::run for other options. Note: the code above is brain-to-terminal and not tested. Use as an example only.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              stereomatching
              wrote on last edited by
              #6

              When I use boost::thread to rename the files(didn't emit any signal)
              I always get warning message, but QRunnable don't get any warning message, weird

              I let QRunnable inherit QObject and emit a signal to update the QProgressBar
              Even all of the file are already rename(I print out "finish" after the task finish their job)
              the GUI still "stall" and need to wait a long time for it to "wake up" but the progress bar is alive now.

              I use two FileSystemModel to nagivate the files in the same folder(since I don't familiar with
              model/view yet), looks like I should use proxyModel to alleviate the burden of CPU.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved