如何更改此类的变量

2024-09-30 06:17:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python新手,来自Java,我想更新初始化类中的一个变量
这是我的完整代码

import datetime import time import threading

from tkinter import * from ibapi.client import EClient, TickAttribBidAsk from ibapi.wrapper import EWrapper, TickTypeEnum from ibapi.contract import Contract


class TestApp(EWrapper, EClient):

    def __init__(self):
        EClient.__init__(self, self)

    def tickPrice(self, reqId, tickType, price, attrib):
        print("Tick price. Ticker Id:", reqId, "tickType:", TickTypeEnum.to_str(tickType), "Price:", price, end=' ')

    def tickByTickBidAsk(self, reqId: int, time: int, bidPrice: float, askPrice: float, bidSize: int, askSize: int, tickAttribBidAsk: TickAttribBidAsk):
        print(bidPrice)
        tkinterApp.price1 = bidPrice


class Application:

    def runTest(self):
        app = TestApp()
        app.connect("127.0.0.1", 7497, 0)
        contract = Contract()
        contract.symbol = "PROG"
        contract.secType = "STK"
        contract.currency = "USD"
        contract.exchange = "SMART"
        contract.primaryExchange = "NASDAQ"

        time.sleep(1)

        app.reqMarketDataType(1)

        app.reqTickByTickData(19003, contract, "BidAsk", 0, True)

        app.run()

    def __init__(self):
        t = threading.Thread(target=self.runTest)
        t.start()
        self.runTest()


class TkinterClass:
    ibkrConnection = Application()
    root = Tk()
    root.title("test")
    root.grid_columnconfigure((0, 1), weight=1)
    titleTicker = Label(root, text="TICKER", bg='black', fg='white', width=100)
    titleRating = Label(root, text="PRICE", bg='black', fg='white', width=100)
    ticker1 = Label(root, text="PROG", bg='black', fg='white', width=100)
    
    price1 = Label(root, text=0, bg='black', fg='white', width=100) # To be changed with every tick
    
    titleTicker.grid(row=1, column=1)
    titleRating.grid(row=1, column=2)
    ticker1.grid(row=2, column=1)
    price1.grid(row=2, column=2)
    root.mainloop()


tkinterApp = TkinterClass()

deftickByTickBidAsk是一个回调函数,每隔2秒调用一次 我想更新类TkinterClass中的price1变量,但是当我尝试执行代码时,tkinterApp.price1 = bidPrice行给了我一个名称错误:TkinterClass is not defined

我知道这可能是个错误:)


Tags: textfromimportselfappdefrootlabel
2条回答

如果您这样做可能会有所帮助:

class TkinterClass:
    def __init__(self):
        self.ibkrConnection = Application()
        self.root = Tk()
        self.root.title("test")
        self.root.grid_columnconfigure((0, 1), weight=1)
        self.titleTicker = Label(root, text="TICKER", bg='black', fg='white', width=100)
        self.titleRating = Label(root, text="PRICE", bg='black', fg='white', width=100)
        self.ticker1 = Label(root, text="PROG", bg='black', fg='white', width=100)
        self.price1 = Label(root, text=0, bg='black', fg='white', width=100) # To be changed with every tick
        self.titleTicker.grid(row=1, column=1)
        self.titleRating.grid(row=1, column=2)
        self.ticker1.grid(row=2, column=1)
        self.price1.grid(row=2, column=2)
    def run(self):
        self.root.mainloop()

tkinterApp = TkinterClass()
tkinterApp.run()

但是,仍然存在一些问题:

  1. 用数值覆盖tkinterApp.price1{}

要设置标签,请使用:tkinterApp.price1.config(str(value))或使用tkinter{}存储price1文本,并使用该StringVar作为Label

  1. 在两个线程中直接使用tkinterApp.price1变量

如果您在后台线程中乱搞Tk变量,Tk可能会不高兴。我建议在前台线程中运行某种计时器,并轮询在后台更新的变量,因此您只能从前台更新Tk变量

使用root.after(ms, callback)在前台计划回调(在调用root.mainloop()之前)

我不认为在读取另一个线程中更新的Python值时需要threading.Lock,但是在更新和访问逻辑周围添加lock()/unlock()会更安全

几年前我玩过tk,这就是我构建代码的方式。我创建了一个tkinter窗口,并从tkinter类连接到TWS

from tkinter import *
import threading

from ibapi import wrapper
from ibapi.client import EClient
from ibapi.utils import iswrapper #just for decorator
from ibapi.common import *
from ibapi.ticktype import *
from ibapi.contract import Contract

class TkWdow():
    def __init__(self):
        root = Tk()
        frame = Frame(root)
        frame.pack()
        button = Button(frame, text="START", fg="green", command=self.start)
        button.pack(side=LEFT)
        button = Button(frame, text="ReqData", command=self.reqData)
        button.pack(side=LEFT)
        button = Button(frame, text="QUIT", fg="red", command=self.quit)
        button.pack(side=LEFT)
        self.output = Text(root, height=50, width=100)
        self.output.pack(side=BOTTOM)
        self.log("This is where output goes")
        root.mainloop()
        #root.destroy()

    def start(self):
        self.client = TestApp(self)
        self.log("starting")
        self.client.connect("127.0.0.1", 7497, clientId=123)
        thread = threading.Thread(target = self.client.run)
        thread.start()
        
    def log(self, *args):
        for s in args:
            self.output.insert(END, str(s) + " ")
            
        self.output.insert(END, "\n")    
                
    def quit(self):
        self.log("quitting")
        self.client.disconnect()
        
    def reqData(self):
        self.log("reqData")
        cont = Contract()
        cont.symbol = "cl"
        cont.secType = "FUT"
        cont.currency = "USD"
        cont.exchange = "nymex"
        cont.lastTradeDateOrContractMonth = "202112"
        self.client.reqMktData(1, cont, "233", False, False, None)
        
    def cancelMktData(self, reqId:TickerId):
        super().cancelMktData(reqId)
        self.log('sub cancel')
        
    
class TestApp(wrapper.EWrapper, EClient):        
    
    def __init__(self, wdow):
        self.wdow = wdow
        wrapper.EWrapper.__init__(self)
        EClient.__init__(self, wrapper=self)
        
    @iswrapper
    def nextValidId(self, orderId:int):
        self.wdow.log("setting nextValidOrderId: " , orderId)
        self.nextValidOrderId = orderId

    @iswrapper
    def error(self, reqId:TickerId, errorCode:int, errorString:str):
        self.wdow.log("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    @iswrapper
    def tickString(self, reqId:TickerId, tickType:TickType, value:str):
        if tickType == TickTypeEnum.RT_VOLUME:
            self.wdow.log(value)#price,size,time


#if __name__ == "__main__":            
TkWdow()

相关问题 更多 >

    热门问题