使用带有 parameters/entry 的 tkinter 按钮打开另一个 python 文件

Open another python file using tkinter button with parameters/entry

我正在尝试为币安构建一个交易机器人。我已经成功构建了机器人并通过终端使用它。

但是,我想制作一个 GUI,以与在终端中相同的方式运行机器人,只是这次有一个界面。我重建了机器人以连接到 binance 数据流来测试它。通过使用各种“代码”(例如 ethusdt、btcusdt),我可以调整机器人以查看特定流的价格信息。

现在的问题是我可以使用按钮启动程序(链接到bot.py),但我仍然必须在启动后在终端中手动输入代码。

所以我的问题是 - 如何将代码作为参数传递给程序,以便它自动启动,而不必在之后输入它?我基本上想在输入字段中输入代码 (ticker_entry) 并将其传递给 bot.py 代码请求。

这是我为 bot.py 编写的代码:

import websocket
import json
import pprint
from colorama import Fore, Back, Style
import numpy as np
import tkinter as tk
tmp = [1]


print("eg. ethusdt = ETH/USDT")
ticker = input(Fore.YELLOW + "Enter ticker here: ")
print(Style.RESET_ALL)


SOCKET="wss://stream.binance.com:9443/ws/"+ ticker +"@kline_1m"




def on_open(ws):
   print('Connection established')

def on_close(ws):
   print("Connection closed")

def on_message(ws, message):

   global tmp
   

   print("waiting for candle to close..")
   
   json_message = json.loads(message)

   

   candle = json_message['k']

   
   is_candle_closed = candle['x']
   close = candle['c']
   
   

   if is_candle_closed:
       
       

       print("\n")
       print(Fore.RED + "Last candle closed at: ")
       print(*tmp, sep= ' , ')
       print(Style.RESET_ALL)
       print("\n")
       print(Fore.GREEN +"New candle closed at: \n{}".format(close))
       print("\n")
       print(Style.RESET_ALL)

       tmp.pop(0)
       tmp.append(float(close))
       
          

ws = websocket.WebSocketApp(SOCKET, on_open=on_open, on_close=on_close, on_message=on_message)
ws.run_forever()

这是我用 tkinter 模块编写的代码:

from tkinter import *
from tkinter import filedialog
import os

root = Tk()
WIDTH = 396
HEIGHT = 594
root.title('CheckBot')
root.geometry("396x594")

bg = PhotoImage(file = "rocket.png")

def start_bot(ticker_entry):
    trader = 'bot.py'
    os.system('"%s"' % trader)


#Creating canvas
my_canvas = Canvas(root, width=WIDTH, height=HEIGHT)
my_canvas.pack(fill="both", expand=True)

#Setting image in canvas
my_canvas.create_image(0,0, image=bg, anchor="nw")

#Adding a label

my_canvas.create_text(200,30, text="Enter the ticker to trade", font=("Bembo Bold Italic", 15), fill="#cc5200")

ticker_entry = Entry(my_canvas, bg='white')
ticker.pack(pady=50)

my_canvas.create_text(200,100, text="Enter amount to trade", font=("Bembo Bold Italic", 15), fill="#cc5200")

amount = Entry(my_canvas, bg='white')
amount.pack(pady=10)

trade_button = Button(my_canvas, text='Start trading', bg='#00b359', fg='#000099', command=lambda:start_bot(ticker))
trade_button.pack(pady=70)


root.mainloop()

您可以将其作为命令行参数传递。

import sys
ticker = ""
if len(sys.argv) > 1:
    ticker = sys.argv[1]

然后,如果ticker不为空,就填入文本框,然后自己调用start_bot

通常,使用 os.system() 生成全新的 CMD shell 并不是最佳做法,最好将所有主要功能放在一个函数中,然后导入该函数并调用它。

而不是在 tkinter 文件中写入:

def start_bot(ticker_entry):
    trader = 'bot.py'
    os.system('"%s"' % trader)

采用 bot.py 的逻辑并将其放入单个函数中,如下所示:

def start_bot(ticker):
    print("eg. ethusdt = ETH/USDT")
    print(Style.RESET_ALL)

    SOCKET="wss://stream.binance.com:9443/ws/"+ ticker +"@kline_1m"

    ws = websocket.WebSocketApp(SOCKET, on_open=on_open, on_close=on_close, on_message=on_message)
    ws.run_forever()

然后,返回 tkinter 文件,您只需使用 from bot import start_bot 导入起始函数,逻辑应该保持完整。

但是,如果您不想更改代码的任何主要方面,并想继续使用 os.system(),那么还有另一种解决方案可以解决您的问题(同样,强烈建议使用上面的解决方案,因为你不依赖冗余的 os.system() 调用,这会浪费更多 CPU 和 RAM 资源)。

当您运行一个文件时,您可以在命令行中指定文件参数。这些参数会传递给脚本,但如果不使用它们,它们将不会执行任何操作。然而,在你的情况下,既然你想访问它们,你可以这样做:

from sys import argv

# Get the first command line argument
first_argument = argv[1]

# The thing to notice here is that you start from the index 1, since 0 is the script name. (When you run a python script, you are calling the python.exe file, and the script name is the first argument)

这与您的问题有什么联系?好吧,因为您已经在命令行中 运行 设置了 bot.py 文件(使用 os.system()),您可以添加一个命令行参数来指定代码。然后,从 bot.py,您可以从 sys.argv.

获取代码值
def start_bot(ticker_entry):
    trader = 'bot.py'
    os.system('"{}" "{}"'.format(trader, ticker_entry)) # Pass the ticker after the script name

并且在 bot.py 文件中...

from sys import argv
ticker = argv[1]