Rename a lot of files by QFile and QFileSystemModel
-
my pc : lenovo G770
compiler : minGW 4.6.2(32bits)
Qt version : 4.8.1I 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
-
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?
-
bq. disabling the view
I tried to change the rootIndex of the view, but the model
still update automaticallybq. 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
-
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(rootPath + "/kkk" + QString::number(i) + ".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 -
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(m_fromPath); 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.
-
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, weirdI 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.