如何用Python简易GUI从API URL显示图片?报错及替代方案咨询
解决随机表情包生成器中的TypeError: 'module' object is not callable错误及优化实现
问题说明
我要做一个随机表情包生成器,用PySimpleGUI和PIL等库编写代码时,调用API读取图片出现TypeError: 'module' object is not callable错误。以下是我的代码和API响应示例:
原代码
import PySimpleGUI as sg from PIL import Image import requests, json cutURL = 'https://meme-api-python.herokuapp.com/gimme' imageURL = json.loads(requests.get(cutURL).content)["url"] img = Image(requests.get(imageURL).content) img_box = sg.Image(img) window = sg.Window('', [[img_box]]) while True: event, values = window.read() if event is None: break window.close()
API响应示例
postLink "https://redd.it/yyjl2e" subreddit "dankmemes" title "Everything's fixed" url "https://i.redd.it/put9bi0vjp0a1.jpg"
错误原因
报错的核心问题是PIL的Image是模块而非可调用函数,直接用Image(requests.get(imageURL).content)尝试创建图片对象,相当于调用模块本身,必然触发module not callable错误。此外,requests.get()返回的二进制内容需要包装成类文件对象才能被PIL读取。
修复方案
- 导入
io模块,用BytesIO将图片二进制内容包装为类文件对象; - 使用
Image.open()方法(而非直接调用Image模块)加载图片; - 将PIL图片对象转换为字节流,适配PySimpleGUI的
Image组件要求; - 新增「刷新」按钮,实现点击切换新表情包的功能。
修复后完整代码
import PySimpleGUI as sg from PIL import Image import requests, json import io def get_random_meme(): cutURL = 'https://meme-api-python.herokuapp.com/gimme' # 直接用requests的json()方法解析响应,无需手动json.loads resp = requests.get(cutURL).json() image_url = resp["url"] # 读取图片二进制内容并包装为类文件对象 img_data = requests.get(image_url).content img = Image.open(io.BytesIO(img_data)) # 将PIL图片转为字节流,供PySimpleGUI显示 buf = io.BytesIO() img.save(buf, format='PNG') return buf.getvalue() # 构建GUI布局 layout = [ [sg.Image(data=get_random_meme(), key='-IMAGE-')], [sg.Button('刷新表情包'), sg.Button('退出')] ] window = sg.Window('随机表情包生成器', layout) while True: event, values = window.read() if event in (None, '退出'): break if event == '刷新表情包': # 更新图片内容 window['-IMAGE-'].update(data=get_random_meme()) window.close()
替代实现思路
如果不需要对图片做裁剪、滤镜等PIL处理,可直接跳过PIL,将API返回的图片二进制内容直接传给PySimpleGUI的Image组件,简化代码:
import PySimpleGUI as sg import requests, json def get_random_meme_bytes(): cutURL = 'https://meme-api-python.herokuapp.com/gimme' image_url = requests.get(cutURL).json()["url"] return requests.get(image_url).content layout = [ [sg.Image(data=get_random_meme_bytes(), key='-IMAGE-')], [sg.Button('刷新'), sg.Button('退出')] ] window = sg.Window('随机表情包生成器', layout) while True: event, values = window.read() if event in (None, '退出'): break if event == '刷新': window['-IMAGE-'].update(data=get_random_meme_bytes()) window.close()
内容的提问来源于stack exchange,提问作者animesh chaudhri
相关产品推荐
相关产品推荐

