0

lambda: ...我在我的程序中使用时遇到问题。因为我不希望我的 TkInter GUI 自动执行这些功能,所以我正在使用lambda. 问题是因为Button3它使我的程序崩溃,我不知道为什么。如果没有 lambda,它绝对可以正常工作。这是我的代码:

import ogr, osr, sys, os
import psycopg2
import ppygis
from datetime import datetime, date
import time
import re
from Tkinter import *
import tkFileDialog
from tkFileDialog import askopenfilename # Open dialog box
from tkMessageBox import showerror

class trip_calculator:

    def __init__(self):
        global root
        root = Tk()

        def open_file_dialog():
            returned_values = {} 
            returned_values['filename'] = askopenfilename()
            Label(root, text= returned_values.get('filename')[52:] + '     selected').grid(row=2)    

            filepath = returned_values.get('filename')

            #OPEN GPX DRIVER
            driver = ogr.GetDriverByName('GPX')
            datasource = driver.Open(filepath)

            if datasource is None:
                print 'not open'
            else:
                print 'open'

            #GEOMETRY
            datasource_layer = datasource.GetLayer(2)

            #GRAB TIMESTAMPS, ELEVATION, CADENCE ETC.
            datasource_layer2 = datasource.GetLayer(4)

            #GRAB GEOMETRY INFORMATION AND TRANSFORM TO UTM
            datasource_feature = datasource_layer.GetNextFeature()
            geoSR = osr.SpatialReference()
            geoSR.ImportFromEPSG(4326) 
            utmSR = osr.SpatialReference()
            utmSR.ImportFromEPSG(32633) 
            coordTrans = osr.CoordinateTransformation(geoSR, utmSR)
            geom = datasource_feature.GetGeometryRef()
            geom1 = geom.Simplify(0)
            geom.Transform(coordTrans)
            geom1.Transform(coordTrans)

            Label(root, text= 'geometries transformed successfully').grid(row=2, column=5)    
            #
            # This is where the crash of Python occurs, 
            # `lambda: calculation(...)` won't start. 
            # It crashes at `features = iter(datasource_layer2)`
            #
            self.button3 = Button(root, text='calculate attributes',   command=lambda:calculation(self,geom1,datasource_layer2)).grid(row=10, column=10, pady=10, padx=10)

        def quit_me():
            root.quit()


        def calculation(self, geom1, datasource_layer2):
        #NET AND GROSS TIME CALCULATION
            timestamps_net = []  
            timestamps_net_helper = []  
            timestamps_elapsed = []  
            elevation_helper = []
            print datasource_layer2
            features = iter(datasource_layer2)
            next(features)
            for feature in features:
                if len(timestamps_net_helper) == 2:
                    timestamps_net_helper = timestamps_net_helper[-1:] 
                timestamp = feature.GetField(4)
                elevation =  feature.GetField(3)
                elevation_helper.append(elevation)
                timestamp_stripped = timestamp[:-3]
                day = timestamp[:-11]
                #FOR GROSS CALCULATION 
                timestamps_elapsed.append(timestamp_stripped)
                #FOR NET CALCULATION
                timestamps_net_helper.append(timestamp_stripped)
                if len(timestamps_net_helper) == 2:
                    #CALCULATE SECONDS BETWEEN
                    time_a = datetime.strptime(timestamps_net_helper[0], "%Y/%m/%d %H:%M:%S") 
                    time_b = datetime.strptime(timestamps_net_helper[1], "%Y/%m/%d %H:%M:%S") 
                    time_difference = time.mktime(time_b.timetuple()) - time.mktime(time_a.timetuple())
                    #IF SECONDS LESS THAN 20 BETWEEN GPS TIMESTAMP THEN ADD UP NET TIME
                    if time_difference < 20:
                        timestamps_net.append(time_difference)
            seconds = sum(timestamps_net)
            hours = seconds/60/60
            time_length_net = time.strftime('%H:%M:%S', time.gmtime(seconds))

            #CLIMB.....
            positive_climb = []
            negative_climb = []
            for a, b in zip(elevation_helper, elevation_helper[1:]):
                if a > 0.0 and b > 0.0:
                    if b > a:
                        positive_climb.append(b-a)
                    elif b == a:
                        pass
                    else:
                        negative_climb.append(a-b)
            positive_climb = sum(positive_climb)
            negative_climb = sum(negative_climb)

            #GROSS (ELAPSED TIME)
            start = datetime.strptime(timestamps_elapsed[0], "%Y/%m/%d %H:%M:%S")  
            end = datetime.strptime(timestamps_elapsed[-1], "%Y/%m/%d %H:%M:%S")
            time_length = end - start

            #LENGTH
            length_km = float(geom1.Length()/1000)

            #AVERAGE SPEED
            avg_speed = (geom1.Length()/1000)/hours

            #CREATE LINESTRING FOR PPYGIS AND OGR LINESTRING
            myLine = ogr.Geometry(ogr.wkbLineString)
            polyline = []
            for z in range(geom1.GetPointCount()):
                x = geom1.GetX(z)
                y = geom1.GetY(z)
                myLine.AddPoint(x, y)
                point = ppygis.Point(x, y)
                polyline.append(point)
            myLine_ppy = ppygis.LineString(polyline)

            Label(root, text= time_length).grid(row=10, column=5)  
            Label(root, text= length_km).grid(row=11, column=5)  
            Label(root, text= avg_speed).grid(row=12, column=5)  



        self.button1 = Button(root, text='browse', command= open_file_dialog).grid(row=0,pady=10, padx=25)
        self.button2 = Button(root, text='close', command= quit_me).grid(row=3, pady=10, padx=25)


    root.mainloop()

trip_calculator()

发生的错误是libc++abi.dylib: pure virtual method called但仅commandbutton3. 任何想法如何解决这一问题?

4

1 回答 1

2

问题可能是由于lambda表达式中的某些参数(即geom1datasource_layer2)是嵌套函数的局部变量,open_file_dialog()并且稍后在按下按钮并返回时不存在。

一个简单的解决方法是使它们成为trip_calculator实例的属性,方法是在函数返回之前的某处添加一个self.datasource_layer2 = datasource_layer2andself.geom1 = geom1语句(或者只是将它们分配给self其他地方并以这种方式引用它们)。

于 2013-10-13T16:02:39.483 回答