繁体   English   中英

终止调用 gdal 函数的 python 线程

[英]Terminate a python thread that calls gdal functions

我有一个使用 gdal 处理图片的程序。 这是在通过单击按钮启动的线程中完成的。 现在,我需要一种在任何给定点终止该线程的方法,也可以单击按钮。 所以我定义了一个当按钮被点击时调用的函数:

def terminateThread(self):
   self.change_button_caption.emit('Start')
   self.print_log.emit('Vorgang abgebrochen')
   self.show_progress.emit(0)
   self.terminate()

当我用睡眠顺序替换实际代码时,这有效。 但是当线程调用 gdal 函数时它不会。 我怎样才能随时终止这个线程?

这是线程:

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()

以及与 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)

看起来 gdal 库是一个绑定 - 从 python 调用非 python 代码。 所以python的terminate()不能停止它,直到执行返回到python部分。 如果您需要立即终止您的函数,您可以使用进程而不是线程。

这可能会有所帮助:

是否可以在子进程中运行函数而无需线程化或编写单独的文件/脚本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM