0

my python GUI app generating and displaying some random values. I have start, stop and calculate buttons. I have randomGenerator function. I am calling it every second. it generates a list of two values. I am appending this lists so that i am getting a list of lists. I just want to reset this list of lists to empty when I press start again after pressing the stop button. method get_max_list should give the maximum of list values generated by the randomGenerator. how do I pass this list value to get_max_list. (sorry I am a python learner)

import tkinter as tk
import random
import threading
start_status = False
calc_list=[]
rand = random.Random()

def randomGenerator():
    global calc_list
    if start_status:
        outputs = []
        Out1= rand.randrange(0,100,1)
        Out2= rand.randrange(0,100,1)
        outputs.append(Out1)
        outputs.append(Out2)

        output_1.set(Out1)  #to display in the GUI
        output_2.set(Out2)
        calc_list.append(outputs)       #i am trying to rest this to empty #when i press start after pressing stopping. 
        print(calc_list)
    win.after(1000, randomGenerator)

def start_me():
    global start_status
    start_status = True
    stopButton.config(state="normal")
    startButton.config(state="disabled")
    calcButton.config(state="disabled")
    calc_list=[]  #it doesn't work

def stop_me():
    global start_status
    start_status = False
    startButton.config(state="normal")
    stopButton.config(state="disabled")
    calcButton.config(state="normal")

def get_max_list(calc_list): #this doesn't work ?
    return [max(x) for x in zip(*calc_list)]
win = tk.Tk()
win.geometry('800x800')


output_1 = tk.StringVar()
output_2 = tk.StringVar()
output_1_label = tk.Label(win, textvariable=output_1)
output_1_label.place(x=200, y=100)

output_2_label = tk.Label(win, textvariable=output_2)
output_2_label.place(x=200, y=200)

startButton = tk.Button(win, text="Start" command = lambda:threading.Thread(target = start_me).start())
startButton.place(x=200, y=500)

stopButton = tk.Button(win, text="Stop", state=tk.DISABLED,  command= lambda:threading.Thread(target = stop_me).start())
stopButton.place(x=200, y=600)

calcButton = tk.Button(win, text="calculate", state=tk.DISABLED, command= lambda:threading.Thread(target = get_max_list).start())
calcButton.place(x=200, y=700)

win.after(1000, randomGenerator)
win.mainloop()
master_yoda
  • 463
  • 3
  • 11
  • You are already declaring `global` for `start_status` in your `start_me` function. Can't you just add `calc_list` to your global declaration, e.g. `global start_status, calc_list`? – Henry Yik Jul 16 '19 at 07:21
  • but I can't initialize as an empty list if I do so. I am getting error `global calc_list=[]` tried this, got invalid syntax error – master_yoda Jul 16 '19 at 07:27
  • 1
    Read [Using global variables in a function](https://stackoverflow.com/questions/423379/using-global-variables-in-a-function). – Henry Yik Jul 16 '19 at 07:28
  • defined `global calc_list` inside randomGenerator method. still got an error when pressed the calculate button `TypeError: get_max_list() missing 1 required positional argument: 'calc_list'` – master_yoda Jul 16 '19 at 07:35

1 Answers1

1

For the first problem, as mentioned you didn't declare global for your list calc_list.

def start_me():
    global start_status, calc_list
    ...
    calc_list=[]

And for your get_max_list function, it expects an argument calc_list. You will need to provide the list as an argument by modifying your thread lambda function:

calcButton = tk.Button(win, text="calculate", state=tk.DISABLED, command= lambda:threading.Thread(target = get_max_list,args=(calc_list,)).start())

Or simply have your function not take an arg at all:

def get_max_list():
    return [max(x) for x in zip(*calc_list)]
Henry Yik
  • 22,275
  • 4
  • 18
  • 40
  • Thanks. it somehow solved all my problems except a new one. if I press calculate button after 4 seconds, `TypeError: get_max_list() takes 1 positional argument but 4 were given`. as there is a new `calc_list` every second. I dunno why isn't accepting the last one only! – master_yoda Jul 16 '19 at 07:56
  • Solved it! just removed the argument in function definition – master_yoda Jul 16 '19 at 08:00