You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter开发PancakeFactory合约PairCreated事件监听GUI异常求助

Tkinter结合PancakeFactory pairCreated事件监听脚本修复方案

问题原因

  • 按钮回调参数错误:定义Button的command属性时写的是main(),加括号会导致代码运行到这一行时直接执行main函数,不需要等待用户点击按钮。而main函数内的asyncio无限循环会直接阻塞Tkinter的窗口渲染逻辑,所以不会弹出GUI窗口,直接跑监听逻辑
  • 事件循环冲突:Tkinter本身的主线程事件循环和asyncio的异步事件循环无法同时在主线程运行,就算点击按钮后再执行main,也会直接卡死GUI窗口
  • 代码存在隐含错误:Web3实例化行缺少右括号、没有导入datetime模块、缺少toDict方法实现

修复后代码

from tkinter import *
from web3 import Web3
import json
import asyncio
import datetime
import threading

# 事件转字典工具方法
def toDict(dictable):
    return dict(dictable)

window = Tk()
window.geometry('500x250')
window.title('pair created')

factory = '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73' 
  
bsc = 'wss://speedy-nodes-nyc.moralis.io/********************************'                                                  
# 补全缺失的右括号
w3 = Web3(Web3.WebsocketProvider(bsc))

with open('D:/BOT/BOT/python/ABI/factoryABI.txt') as file:                            
     factory_abi = json.load(file)

contractF = w3.eth.contract(address = factory, abi = factory_abi)      

def handle_event(event):                                                                
    pairData = toDict(event)                                                                              
    now = datetime.datetime.now()
    print('======== Pair created ========', now.strftime("%H:%M:%S %Y-%m-%d"))          
    print('Block number:',w3.eth.block_number)                                          
    print('token0:',pairData['args']['token0'])                                         
    print('token1:',pairData['args']['token1'])                                         
   

async def log_loop(event_filter, poll_interval):                              
    while True:
        for PairCreated in event_filter.get_new_entries():
            handle_event(PairCreated)
        await asyncio.sleep(poll_interval)

def main():                                                                   
    event_filter = contractF.events.PairCreated.createFilter(fromBlock='latest')
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        loop.run_until_complete(
            asyncio.gather(
                log_loop(event_filter, 1)))
    finally:
       loop.close()

# 点击按钮后在子线程启动监听,不阻塞主线程GUI
def start_listen():
    t = threading.Thread(target=main, daemon=True)
    t.start()

# command参数传入函数引用,不要加括号
buttonStart = Button(window, text = 'Start',command = start_listen)
buttonStart.pack()
window.mainloop()

修复说明

  • 按钮回调改为start_listen函数引用,不会在代码初始化时直接执行监听逻辑
  • 新增start_listen方法将监听逻辑丢到守护子线程运行,不阻塞Tkinter主线程的渲染和交互
  • 补全了缺失的导入、语法错误和toDict工具方法
  • 改用asyncio.new_event_loop()避免和主线程可能存在的事件循环冲突

内容的提问来源于stack exchange,提问作者Samuel Alibien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:27:03