如何将VB委托转换为python事件处理程序? [英] How do I convert a VB delegate into a python event handler?

查看:85
本文介绍了如何将VB委托转换为python事件处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用delegate (事件)的VB代码重写为python="nofollow noreferrer"> python.net .

I have to rewrite the following VB code that is subscribing to a delegate (event), into python, using python.net.

Imports MtApi

Public Class Form1
    Private apiClient As MtApiClient

    Public Sub New()
        InitializeComponent()
        apiClient = New MtApiClient
        AddHandler apiClient.QuoteUpdated, AddressOf QuoteUpdatedHandler
    End Sub

    Sub QuoteUpdatedHandler(sender As Object, symbol As String, bid As Double, ask As Double)
        Dim quoteSrt As String
        quoteSrt = symbol + ": Bid = " + bid.ToString() + "; Ask = " + ask.ToString()
        ListBoxQuotesUpdate.Invoke(Sub()
                                       ListBoxQuotesUpdate.Items.Add(quoteSrt)
                                   End Sub)
        Console.WriteLine(quoteSrt)
    End Sub

    ' These can be ignored for this discussion
    Private Sub btnConnect_Click(sender As System.Object, e As System.EventArgs) Handles btnConnect.Click
        apiClient.BeginConnect(8222)
    End Sub

    Private Sub btnDisconnect_Click(sender As System.Object, e As System.EventArgs) Handles btnDisconnect.Click
        apiClient.BeginDisconnect()
    End Sub
End Class

此VB代码是 mtapi .NET网桥的VB应用程序的一部分.

This VB code is part of a VB app for the mtapi .NET bridge.

问:将VB委托转换为python事件处理程序的正确方法是什么?

我已经尝试了以下几种变化:

I have already tried many variation of the following:

...
import MtApi as mt
...
# apiClient_QuoteUpdated(object sender, string symbol, double bid, double ask)
def printTick(symbol, ask, bid):
    print('Tick: Symbol: {}  Ask: {:.5f}  Bid: {:.5f}'.format(symbol, ask, bid))


class OnTick:
    def __init__(self):
        self.listeners = []

    def __iadd__(self, listener):
        # Shortcut for using += to add a listener
        self.listeners.append(listener)
        return self

    def notify(self, *args, **kwargs):
        for listener in self.listeners:
            listener(*args, **kwargs)

mtc = mt.MtApiClient()
res = mtc.BeginConnect('127.0.0.1', 8222);

# This Works!
newTick = OnTick()
newTick += printTick
newTick.notify(SYM, 1.12400, 1.12300)

# This does NOT work!
newTick.notify(mtc.QuoteUpdate())
# TypeError: 'EventBinding' object is not callable

在这里查看答案:

推荐答案

此答案密切相关问题是,问题过于复杂了委托代码.我们完全不需要 OnTick 类,并且意识到 QuoteUpdatedHandler() 需要 4个参数,因此我们用它替换 printTick(...).

As closely related to this answer in a similar question, the issue was in over-complicating the delegate code. We simply don't need the OnTick class and also realizing that the QuoteUpdatedHandler() need 4 arguments, so we replace the printTick(...) with that.

(当然,如果您确实想使某事物变得更复杂或优雅,那么您确实想在一个类中创建它.)

(Of course if you do want to make somethng a little more complicated or elegant, you do want to create this in a class.)

然后,与VB委托等效的Python代码变为:

Then the equivalent Python code to for the VB delegate, become:

...
def QuoteUpdatedHandler(source, sym, bid, ask) :
    qstr = '{}: {:.5f} {:.5f}'.format(sym,bid,ask)
    print(qstr)

...
mtc = mt.MtApiClient()

print('Connecting...')
res = mtc.BeginConnect('127.0.0.1', 8222);

# VB: AddHandler mtc.QuoteUpdated, AddressOf QuoteUpdatedHandler
# Because we want the "AddressOf" of the function, we don't use the invoking "()"
mtc.QuoteUpdated += QuoteUpdatedHandler

print('ok')

# Now run in a loop and wait for the events:
while 1:
    pass
    try: 
        time.sleep(0.1)
    except KeyboardInterrupt:
        print('\n  Break!')
        break

if (mtc.IsConnected()) :
    mtc.PlaySound("tick")
    mtc.BeginDisconnect()
print('\n  Done!')

sys.exit(2)

这篇关于如何将VB委托转换为python事件处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆