终止调用gdal函数的python线程

问题描述

我有一个使用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部分之前停止它。如果需要立即终止函数,则可以使用进程而不是线程。

这可能会有所帮助:

Is it possible to run function in a subprocess without threading or writing a separate file/script.

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...