i have a program that uses gdal to process pictures. That is done in a thread that is started with a button click. Now, i need a way to terminate this thread at any given point, also with a button click. So i defined a function that i call when the button is clicked:
def terminateThread(self):
self.change_button_caption.emit('Start')
self.print_log.emit('Vorgang abgebrochen')
self.show_progress.emit(0)
self.terminate()
When i replace the actual code with a sleep order, this works. But it doesn't when the thread called a gdal function. How can i achieve the termination of this thread at any time?
this is the thread:
class MapThread(QThread):
print_log = Signal(str)
show_progress = Signal(int)
change_button_caption = Signal(str)
def __init__(self, path, tab_filelist, targetpath):
QThread.__init__(self)
self.path = path
self.tab_filelist = tab_filelist
self.targetpath = targetpath
def run(self):
self.change_button_caption.emit('Stop')
print('MapThread run', flush=True)
# try:
from osgeo import gdal
from osgeo import osr
self.show_progress.emit(0)
filename = self.tab_filelist[0].rsplit('\\', 1)[1].rsplit('.', 1)[0]
path2 = self.targetpath + "\\" + filename + ".vrt"
pathout = self.targetpath + "\\" + filename + ".mbtiles"
d = gdal.Open(self.path)
proj = osr.SpatialReference(wkt=d.GetProjection())
self.print_log.emit('EPSG Code der Bilddaten: ' + proj.GetAttrValue('AUTHORITY', 1))
# Vituelles Raster erzeugen
vrt_options = gdal.BuildVRTOptions(resampleAlg='cubic', outputSRS=proj)
gdal.BuildVRT(path2, self.tab_filelist, options=vrt_options)
print('VRT Datei erzeugt', flush=True)
self.print_log.emit('VRT Datei erzeugt')
self.show_progress.emit(10)
# mbtiles generieren
creation_options = ["TILE_FORMAT=JPEG", "QUALITY=90"]
src_ds = gdal.Open(path2)
gdal.Translate(pathout, src_ds, format='mbtiles', creationOptions=creation_options)
print('MB Tiles generiert', flush=True)
self.print_log.emit('MB Tiles generiert')
self.show_progress.emit(75)
# Overviews erzeugen
Image = gdal.Open(pathout, 1)
gdal.SetConfigOption("COMPRESS_OVERVIEW", "DEFLATE")
Image.BuildOverviews("AVERAGE", [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048])
self.show_progress.emit(100)
print('Overviews erfolgreich berechnet', flush=True)
self.print_log.emit('Overviews erfolgreich berechnet')
self.change_button_caption.emit('Start')
# except Exception as err:
# print(err)
def terminateThread(self):
self.change_button_caption.emit('Start')
self.print_log.emit('Vorgang abgebrochen')
self.show_progress.emit(0)
self.terminate()
and the functions for comunicating with the ui:
@Slot(str)
def printLog(self, msg):
self.ui.list_status.addItem(msg)
@Slot(int)
def showProgress(self, value):
self.ui.progressBar.setValue(value)
@Slot(str)
def changeCaption(self, txt):
self.ui.btn_start_mbtiles.setText(txt)
Looks like gdal library is a binding - non-python code is called from python. So python's terminate()
just can't stop it until execution returned to the python part. If you need to terminate your function immediatly, you may use processes instead of threads.
This may be helpful:
Is it possible to run function in a subprocess without threading or writing a separate file/script.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.