简体   繁体   English

使用带有参数/条目的 tkinter 按钮打开另一个 python 文件

[英]Open another python file using tkinter button with parameters/entry

I'm trying to build a trading bot for binance.我正在尝试为币安构建一个交易机器人。 I've managed to build the bot and use it via terminal.我已经设法构建了机器人并通过终端使用它。

However, I want to make a GUI that runs the bot in the same way it would in terminal, except this time with an interface.但是,我想制作一个 GUI,它以与终端中相同的方式运行机器人,除了这次有一个界面。 I've rebuilt the bot to connect to the binance data-stream to test it.我已经重建了机器人以连接到 binance 数据流以对其进行测试。 By using various "tickers" (eg. ethusdt, btcusdt), I can tune the bot to look at specific streams for price information.通过使用各种“代码”(例如 ethusdt、btcusdt),我可以调整机器人以查看特定流以获取价格信息。

The problem now is that I can start the program using the button (linked to bot.py ), but I still have to enter the ticker manually in the terminal after it starts.现在的问题是我可以使用按钮(链接到bot.py )启动程序,但是启动后我仍然必须在终端中手动输入代码。

So my question is- how do I pass the ticker as a parameter to the program so that it starts automatically, and not have to enter it after?所以我的问题是 - 我如何将股票代码作为参数传递给程序,以便它自动启动,而不必在之后输入它? I basically want to enter a ticker in the entry field (ticker_entry) and pass it in to the bot.py ticker request.我基本上想在输入字段(ticker_entry)中输入一个代码并将其传递给bot.py代码请求。

Here's the code I've written for 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()

And here is the code I've written with the tkinter module:这是我用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()

Generally, it isn't the best practice to spawn a whole new CMD shell using os.system() , and it is better to put all the main functionality in a function, then import that function and call it. Generally, it isn't the best practice to spawn a whole new CMD shell using os.system() , and it is better to put all the main functionality in a function, then import that function and call it.

Instead of writing this in the tkinter file:而不是在tkinter文件中写这个:

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

Take the logic of bot.py and put it into a single function like so:bot.py的逻辑放入单个 function 中,如下所示:

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()

Then, back in the tkinter file, you can simply import the starting function with from bot import start_bot , and the logic should stay in tact.然后,回到tkinter文件,您可以简单地使用from bot import start_bot ,并且逻辑应该保持完整。

However, if you don't want to change any major aspect of your code, and want to keep using os.system() , then there yet another solution to your problem (again, it is highly recommended to use the above solution, since you are not relying on a redundant os.system() call which will waste more CPU and RAM resources).但是,如果您不想更改代码的任何主要方面,并且想继续使用os.system() ,那么您的问题还有另一种解决方案(同样,强烈建议使用上述解决方案,因为您不依赖于多余的os.system()调用,这会浪费更多的 CPU 和 RAM 资源)。

When you run a file, you can specify file arguments in the command line.运行文件时,可以在命令行中指定文件 arguments。 These arguments get passed to the script, but they don't do anything if they are not used.这些 arguments 被传递给脚本,但如果不使用它们就不会做任何事情。 However, in your case, since you want to access them, you can do it like so:但是,在您的情况下,由于您想访问它们,您可以这样做:

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)

How does this connect with your question?这与您的问题有何联系? Well, since you are already running the bot.py file in the command line (using os.system() ), you can add a command line argument to specify the ticker.好吧,既然您已经在命令行中运行了bot.py文件(使用os.system() ),您可以添加一个命令行参数来指定代码。 Then, from bot.py , you can get that ticker value from sys.argv .然后,从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

And in the bot.py file...bot.py文件中...

from sys import argv
ticker = argv[1]

You can pass it as a command-line parameter.您可以将其作为命令行参数传递。

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

Then, if ticker is not empty, just fill in the text box, and call start_bot yourself.然后,如果ticker不为空,只需填写文本框,并自己调用start_bot

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM