Callable object not callable报错:按钮点击调用地图生成函数失败求助
问题根因
你的报错完全是事件绑定的写法错误导致的:
button.on_click(generate_map())这里给generate_map加了括号,会立即执行这个函数,把函数返回的Map对象m传给on_click方法。而on_click要求传入的是可调用的函数引用,等用户点击按钮时才触发执行,所以运行时自然会报「map对象不可调用」的错误。你用callable检测generate_map返回True是对的,因为函数本身确实可调用,你传进on_click的是它的执行返回值,不是函数本身。- ipywidgets的
on_click绑定的回调函数,默认会把被点击的按钮实例作为第一个参数传入,你现在定义的generate_map没有接收参数,就算修复了绑定写法,点击触发时也会抛出参数不匹配的错误。
修复方法
按照以下两点修改即可:
- 给
generate_map加一个占位参数接收按钮实例(用不到的话随便命名就行) - 绑定点击事件时只写函数名,不要加括号
如果需要避免每次点击都重复添加用户位置标记,还可以加一段清除旧用户标记的逻辑。
修改后的完整代码参考:
import urllib.request import json import datetime import ipywidgets as widgets from ipyleaflet import Map, basemaps, AwesomeIcon, Marker # 从接口获取ISS当前位置 url = 'http://api.open-notify.org/iss-now.json' response = urllib.request.urlopen(url) result = json.loads(response.read()) location = result['iss_position'] lat = float(location['latitude']) lon = float(location['longitude']) # 生成底图,标记ISS当前位置 center = [lat, lon] zoom = 1.5 m = Map(basemap=basemaps.Esri.WorldImagery, center=center, zoom=zoom, close_popup_on_click=False) icon1 = AwesomeIcon(name='space-shuttle', marker_color='blue', icon_color='white', spin=False) marker = Marker(icon=icon1, location=(lat, lon), draggable=False) m.add_layer(marker) # 经纬度输入组件 input_text_lat = widgets.IntText(value=-35, description='纬度:') input_text_lon = widgets.IntText(value=150, description='经度:') # 点击回调函数,加b参数接收按钮实例 def generate_map(b): user_lat = input_text_lat.value user_lon = input_text_lon.value user_location = (user_lat, user_lon) # 获取ISS飞掠时间 url = f'http://api.open-notify.org/iss-pass.json?lat={user_lat}&lon={user_lon}' response = urllib.request.urlopen(url) result = json.loads(response.read()) over_time = result['response'][1]['risetime'] date_time = datetime.datetime.utcfromtimestamp(over_time).strftime('%Y-%m-%d %H:%M:%S') print(f'国际空间站将在 {date_time} 飞掠你的位置') # 清除之前的用户标记,避免重复添加 for layer in m.layers: if hasattr(layer, 'icon') and layer.icon.name == 'user': m.remove_layer(layer) # 添加新的用户位置标记 icon2 = AwesomeIcon(name='user', marker_color='lightred', icon_color='white', spin=False) marker2 = Marker(icon=icon2, location=user_location, draggable=False, title='你的位置') m.add_layer(marker2) # 生成按钮,绑定事件时不要加括号 button = widgets.Button( description='生成地图', disabled=False, button_style='success', tooltip='点击查询' ) button.on_click(generate_map) # 显示组件和地图 display(input_text_lat, input_text_lon, button, m)
内容的提问来源于stack exchange,提问作者LEJ2474
相关产品推荐
相关产品推荐

