Sunday, 4 February 2018

Python Button Tkinter passing arguments

Python tkinter button widget passing arguments.  In these examples I will show you several ways you can pass values, variables, arguments to a function. You will also learn how to add a right mouse click as well as the left mouse click.  

Save Save
Here is the code to start the tutorial and follow along
from tkinter import *
from tkinter import ttk

class Application(Frame):
    
    """ A GUI application """

    def __init__(self, master):
        """ Initialize the Frame"""
        ttk.Frame.__init__(self, master)

        self.grid()
        self.create_widgets()

    def create_widgets(self):
        # create a normal button
        self.button1 = Button(root, font=('', 16, 'bold'), text='.22 Cents', command=self.do_something)
        self.button1.grid(row=0, column=0, pady=5, padx=5)

        # create a text box (Entry box) to hold the value of the click event
        self.tbValue = Entry(root, font=('', 16, 'bold'), textvariable=varEntryValue).grid(row=1, column=2, pady=5, padx=5)

        # create a text box (Entry box) to hold a average price
        self.tbSet = Entry(root, font=('', 16, 'bold'), textvariable=varAvgPrice).grid(row=1, column=1, pady=5, padx=5)
        
    # button 1 example
    def button1_Click(event, arg):
        average_Price = varAvgPrice.get() # gets a value from the first Entry box
        c = float(average_Price) + arg # adds the value from the ttk .22 button to the first entry box value
        c = round(c, 2) # round off c to 2 decimal places
        varEntryValue.set(c) # sets the value in the second Entry box

    def do_something(self):
        varEntryValue.set('Hello, Hola, Bonjour')    

root = Tk()

root.title("Button Examples in Python")
root.geometry("790x850")
root.attributes("-topmost", True)
varEntryValue = StringVar()
varAvgPrice = StringVar(root, value='105.00')

app = Application(root)

root.mainloop()



Get The Unique id conId Number from TWS

Learn how to get the unique id (conId) from Interactive brokers using a gui application. Every option has a different number since there are so many variations. The contract id (conid) is a number not a symbol, and this number you will need in order to trade options. For example the IBM 170 CALL option with an expiry on January 6, 2017 has a unique id number of  256910869. The number may be different on the next trading day.  I am not sure if they stay the same from now, until the next day until they expire. You can search for a contract id number here: https://pennies.interactivebrokers.com/cstools/contract_info/v3.9/index.php see the code here To access a September 2016 $40 Call option on Netflix : I believe there is a data fee for options. You need to pay for a data feed for the options in order to request data through the API
conID = 3 # Contract ID
symbol = "NFLX" # Netflix’s stock symbol
secType = "OPT" # Security type is an Option (OPT)
expiry = "20170120" # January 2017 Expiry format yyyymmdd
strike = 90 # $90.00 strike price
right = "CALL" # Call option
multiplier = "100" # multiplier 100 shares per contract for options
exchange = "SMART" # Use IB’s Smart Order router to get the prices
currency = "USD" # USD Currency

To access a June 2017 Crude Oil Futures contract set the properties:
conID = 2 # Contract Id
symbol = "CL" # Crude Oil underlying symbol (CL)
secType = "FUT" # Security type is an Future (FUT)
expiry = "20170120" # January 20, 2017 Expiry third Friday of month
exchange = "NYMEX" # Use IB’s Smart Order router to get the prices
To access a foreign exchange quote such as Euro/USD:
conID = 6 # Contract Id
symbol = "EUR" # Euro underlying (base currency) symbol (EUR/USD quote)
secType = "CASH" # Security type is Cash / FX
exchange = "IDEALPRO" # Use the IDEALPRO FX data source
currency = "USD" # Quoted currency is USD
 
Save Save

Listbox Scroll bars Horizontal Vertical

Listbox Scroll bars tkinter Python Copy and paste the highlighted text into the section of your code where you create your widgets, and also add the x and yscrollcommands to the listbox parameters.
# Craig Hammond 2017
# www.sharpertradingimage.com
        # create scroll bars for your listbox
        self.scrollbar_V = Scrollbar(self)
        self.scrollbar_H = Scrollbar(self, orient=HORIZONTAL)
        self.scrollbar_V.grid(row=1, column=1, sticky=N+S+W)
        self.scrollbar_H.grid(row=5, column=0, sticky=N+E+S+W)
        
        # create listbox widget
        self.listbox1 = Listbox(self, font=('', 12), width=15, height=10, yscrollcommand=self.scrollbar_V.set, xscrollcommand=self.scrollbar_H.set)
        self.listbox1.bind('<<ListboxSelect>>', self.select_item)
        self.listbox1.insert(1, 'FB')
        self.listbox1.grid(row=1, column=0)
        # add some text to the listbox 
        evil_corporations = ['EVIL CORPORATIONS y gobiernos', 'cranAAPLe', 'SBUckX', 'XOMobil',
                                  'Any oil company that you care to name',
                                  'OPECs', 'MSFaT', 'AMEXica', 'ALL COUNTRIES THAT DO NOT PROSECUTE THE BANKERS',
                                  'most TRADING FIRMS', 'BUT NOT INTERACTIVE BROKERS BEST COMMISSIONS not as bad',
                                  'banking cartels, the FED', 'las paisas que le gusta la guerra', 'foundations created by evil elitists']
        for evil in evil_corporations:
            self.listbox1.insert('end', evil)
        # also needed for scroll bars
        self.scrollbar_V.config(command=self.listbox1.yview)
        self.scrollbar_H.config(command=self.listbox1.xview)

Python Treeview delete rows

from tkinter import *
from tkinter import ttk

class Application(Frame):
    
    def __init__(self, master):
        """ Initialize the Frame"""
        ttk.Frame.__init__(self, master)
 
        self.grid()
        self.create_widgets()

    def create_widgets(self):
        self.btnConnect = ttk.Button(self, text = "Search Symbol", command=self.search_symbol).grid(row=0, column=0, sticky=W)
        self.btnDisconnect = ttk.Button(self, text = "Add data", command=self.add_data).grid(row=0, column=1, sticky=W)
        self.btnCancelMktData = ttk.Button(self, text = 'Remove All', command=self.remove_all).grid(row=0, column=2, sticky=W)
        self.button_edit = Button(self, font=('',12), text="select row", width=7, command=self.add_data)
        self.button_edit.grid(row=0, column=4)
        
        # create Treeview widget to hold values in a table
        self.tv = ttk.Treeview(root)    

        # create Treeview 
        self.tv = ttk.Treeview(self,  height=8)
        self.tv['columns'] = ('id', 'symbol', 'price', 'trigger', 'shares', 'side', 'type', 'status', 'fill')
        self.tv.heading("#0", text='Time', anchor='w')
        self.tv.column("#0", stretch=NO, width=5, anchor="w")
        self.tv.heading('id', text='ID')
        self.tv.column('id', anchor='center', width=70)
        self.tv.heading('symbol', text='Symbol')
        self.tv.column('symbol', anchor='center', width=70)
        self.tv.heading('price', text='Price')
        self.tv.column('price', anchor='center', width=70)
        self.tv.heading('trigger', text='Trigger')
        self.tv.column('trigger', anchor='center', width=70)
        self.tv.heading('shares', text='Shares')
        self.tv.column('shares', anchor='center', width=100)
        self.tv.heading('side', text='Side')
        self.tv.column('side', anchor='center', width=70)
        self.tv.heading('type', text='Type')
        self.tv.column('type', anchor='center', width=70)
        self.tv.heading('status', text='Status')
        self.tv.column('status', anchor='center', width=100)
        self.tv.heading('fill', text='Fill')
        self.tv.column('fill', anchor='center', width=70)
        self.tv.bind('<ButtonRelease-1>', self.select_item) 
        self.tv.grid(row=1, column=0, columnspan=6, padx=5, pady=5)
        self.treeview = self.tv
##        self.ysb = ttk.Scrollbar(self, orient='vertical', command=self.tv.yview)
##        self.xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tv.xview)
##        self.tv.configure(yscroll=self.ysb.set, xscroll=self.xsb.set)
##        self.ysb.grid(row=1, column=7, sticky='ns')
##        self.xsb.grid(row=2, column=0, sticky='ew')
        
        ttk.Style().configure("Treeview", font= ('', 11), background="#383838", 
        foreground="white", fieldbackground="yellow")

        self.tv.insert("","end",text = "Person",values = ("1254","MSFT","39.39", "", "0/200", "BUY", "LMT", "Filled", "39.39"), tags='hot')
        self.tv.insert("","end",text = "Animal",values = ("1255","MSFT","39.58", ".10", "0/200", "SELL", "TRAIL", "PreSubmitted", "0.00"), tags='cold')
        self.tv.insert("","end",text = "Name",values = ("1256","MSFT","39.58", "", "0/200", "SELL", "LMT", "Submitted", "0.00"), tags='pizza')
        self.tv.insert("","end",text = "Evil Corp",values = ("1258","NFLX","102.55", "", "0/300", "SELL", "LMT", "Submitted", "0.00"), tags='tacos')

    def remove_all(self):
        x = self.tv.get_children()
        print ('get_children values: ', x ,'\n')
        if x != '()': # checks if there is something in the first row
            for child in x:
                self.tv.delete(child)
                
    def search_symbol(self):
        pass

    def add_data(self):
        pass

    def select_item():
        pass

root = Tk()       
app = Application(root)
root.mainloop()


Save Save

Saturday, 3 February 2018

Scrolling 2 text widgets together

I am using the pack() Geometry Manager to place all of the widgets. I opted for the pack() Manager because it is ideal for placing widgets side by side or drop down position. Fortunately, in a text editor, I have all the widgets Placed next to each other or in descending order. It is therefore advantageous to the pack() Manager. We can do the same with the grid() manager also.

Save Save

# Craig Hammond 2018

import tkinter as tk
from tkinter import *


from tkinter import ttk
import re

class SampleTextApp(Frame):
    def __init__(self, master, **kwargs):# this **kwargs is needed for the scroll bar
        ttk.Frame.__init__(self, master)
        self.file_name = None
        self.grid()
        self.create_widgets()

    def create_widgets(self):

        # font varialble to use with all widgets
        my_font = ('', 18)
        
        # add a text box for the line numbers
        self.line_number_text = Text(self, font=my_font, width=4, padx=3, takefocus=0, border=0, background='yellow', state='disabled', wrap='none')
        self.line_number_text.pack(side='left', fill='y')
        
        # add the main text box widget here
        self.main_text = Text(self, font=my_font, wrap='none')
        self.main_text.bind('<KeyPress>', self.on_text_changed)
        self.main_text.pack(expand='yes', fill='both')
        
        # add a scroll bar for the main text widget
        self.scroll_bar = Scrollbar(self.main_text)
        self.scroll_bar.pack(side='right', fill='y')

        # call the scroll bar functions
        self.scroll_bar['command'] = self.on_scrollbar
        self.line_number_text['yscrollcommand'] = self.on_textscroll
        self.main_text['yscrollcommand'] = self.on_textscroll
# this will update the line numbers any time you
        # press a key on the keyboard
        self.main_text.bind('<Any-KeyPress>', self.on_text_changed)
        self.main_text.focus_set()
   
    def on_scrollbar(self, *args):
        self.line_number_text.yview(*args)
        self.main_text.yview(*args)
        
    def on_textscroll(self, *args):
        # Moves scrollbar and scrolls text widgets when the mouse wheel
        # is moved on the text widget
        self.scroll_bar.set(*args)
        self.on_scrollbar('moveto', args[0])
        
    def on_text_changed(self, event=None):
        self.update_line_numbers()
    
    def get_line_numbers(self):
        output = ''
        row, col = self.main_text.index("end").split('.')
        for i in range(1, int(row)):
            output += str(i) + '\n'
        return output

    def update_line_numbers(self, event=None):
        line_numbers = self.get_line_numbers()
        # disables the text widget so the widget does not scroll
        self.main_text.config(state='disabled')
        self.line_number_text.config(state='normal') 
        self.line_number_text.delete('1.0', 'end')
        self.line_number_text.insert('1.0', line_numbers)
        self.line_number_text.config(state='disabled')
        # returns the text widget back to normal
        self.main_text.config(state='normal')

root = Tk()
PROGRAM_NAME = ' My Text Editor '
root.title(PROGRAM_NAME)
root.geometry("600x300")
app = SampleTextApp(root)
app.pack(fill='both', expand='yes')
app.mainloop()