Try the script below. Just change the in_folder
and out_folder
variables to match your own file paths. The in_folder
is the path to the folder where your .tab files are stored and out_folder
is the path to the folder in which you want to save the new shapefiles. I tested this in the Python console in QGIS 3.16 and it worked perfectly with my own file paths.
# path to folder where your .tab files are located
in_folder = 'C:\\Users\\Ben\\Desktop\\GIS Files\\Vector Data\\Global Map_Mi_data'
# path to folder where you want to save your shapefiles
out_folder = 'C:\\Users\\Ben\\Desktop\\GIS Files\\Vector Data\\Global Map_Mi_data\\Shapefiles'
def convert_layer(in_layer, save_location):
out_layer = os.path.join(save_location, f'{in_layer.name.replace(".tab", ".shp")}')
processing.run("gdal:convertformat",
{'INPUT': in_layer.path,
'OPTIONS':'',
'OUTPUT':out_layer})
src_dir = os.scandir(in_folder)
for file in src_dir:
if file.name.endswith('.tab'):
convert_layer(file, out_folder)
However, given that you have a fairly large number of files to convert, I would recommend considering wrapping the operation in a QgsTask
which will run in a background thread, meaning your gui will remain responsive while the task is carried out.
Below is a more sophisticated version of the script above which shows how to do this. In this script I have also used the QFileDialog
class to get the paths to the source and destination folders to make the things a little more versatile and user friendly.
class RunAlg(QgsTask):
alg_finished = pyqtSignal(str)
def __init__(self, desc, in_folder, out_folder):
self.desc = desc
QgsTask.__init__(self, self.desc, QgsTask.CanCancel)
self.in_folder = in_folder
self.out_folder = out_folder
self.src_dir = os.scandir(self.in_folder)
self.tab_list = [file for file in self.src_dir if file.name.endswith('.tab')]
def run(self):
if not self.tab_list:
return False
for count, item in enumerate(self.tab_list):
out_layer = os.path.join(self.out_folder, f'{item.name.replace(".tab", ".shp")}')
if self.isCanceled():
return False
processing.run("gdal:convertformat",
{'INPUT': item.path,
'OPTIONS':'',
'OUTPUT':out_layer})
self.alg_finished.emit(f'{count+1}/{len(self.tab_list)}')
return True
def finished(self, result):
iface.messageBar().clearWidgets()
if result:
iface.messageBar().pushMessage(f'{len(self.tab_list)} files successfully converted')
else:
iface.messageBar().pushMessage('Task failed/cancelled')
class Main():
def __init__(self, in_path, out_path):
self.in_path = in_path
self.out_path = out_path
self.msg = iface.messageBar().createMessage('Converting files...')
self.prog_lbl = QLabel()
self.prog = QProgressBar(self.msg)
self.kill = QPushButton('Cancel', self.msg)
self.kill.clicked.connect(self.cancel_pushed)
self.msg.layout().addWidget(self.prog_lbl)
self.msg.layout().addWidget(self.prog)
self.msg.layout().addWidget(self.kill)
self.task1 = RunAlg('Running: convert format', self.in_path, self.out_path)
self.task1.begun.connect(lambda: iface.messageBar().pushWidget(self.msg))
self.task1.alg_finished.connect(self.update_progress)
def update_progress(self, prog):
self.prog_lbl.setText(prog)
current = int(prog.split('/')[0])
total = int(prog.split('/')[1])
pcnt = (current/total*100)
self.prog.setValue(pcnt)
def start_task(self):
QgsApplication.taskManager().addTask(self.task1)
def cancel_pushed(self):
self.task1.cancel()
iface.messageBar().clearWidgets()
src_path = QFileDialog().getExistingDirectory(iface.mainWindow(), 'Select input folder')
if src_path:
save_path = QFileDialog().getExistingDirectory(iface.mainWindow(), 'Select save folder')
if save_path:
T = Main(src_path, save_path)
T.start_task()
Example result after running the above code in the qgis Python console is shown below: