Why does my canvas image disappear even though I keep a reference? - python

The idea is to have the user click on the color bar and the entry field on the left will get a number from 0 to 100 entered for the user. The problem is the color bar image is blanked, even though I try to keep a reference to it so that it doesn't get garbage collected.
import Tkinter as Tk
class Test(Tk.Frame):
'''Test color bar for user input'''
def __init__(self, parent):
Tk.Frame.__init__(self, parent)
photo_color_bar_01 = Tk.PhotoImage(file = 'color_bar_blue_to_red_020.GIF')
pic_width = photo_color_bar_01.width()
pic_height = photo_color_bar_01.height()
shift_x_01 = 0 # 10
shift_y_01 = 0 # 10
pic_width_plus_border = pic_width + shift_x_01
pic_height_plus_border = pic_height + shift_y_01
x_center = (pic_width_plus_border) / 2.0
y_center = (pic_height_plus_border) / 2.0
My_Labels = ["Input_One", "Input_Two", "Input_Three", "Input_Four"]
Labels = []
variables = []
entrys = []
pic_frames = []
canvases = []
label_row = 0
entry_row = 1
for index in range(len(My_Labels)):
Labels.append(Tk.Label(root, text=My_Labels[index]))
Labels[-1].grid(padx=0, pady=0, row=label_row, column=0)
variables.append(Tk.StringVar())
entrys.append(Tk.Entry(root, textvariable =variables[index]))
entrys[-1].grid(padx=0, pady=0, row=entry_row, column=0)
entrys[-1].delete(0, Tk.END)
entrys[-1].insert(0, "50.00")
pic_frames.append(Tk.Frame(root, bd=4, relief=Tk.RAISED))
pic_frames[-1].grid(padx=0, pady=0, row=entry_row, column=2)
canvases.append(Tk.Canvas(pic_frames[-1], width=pic_width, height=pic_height))
canvases[-1].create_image(x_center, y_center, image=photo_color_bar_01, anchor = Tk.CENTER)
# keep a reference
# http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm
canvases[-1].image = photo_color_bar_01 # keep a reference
canvases[-1].config(cursor="X_cursor")
canvases[-1].grid(padx=0, pady=0, row=entry_row, column=3)
canvases[-1].bind("<ButtonPress-1>", lambda event, arg=index: self.pick_LMB(event, index))
canvases[-1].bind("<ButtonPress-2>", self.pick_MMB)
label_row += 2
entry_row += 2
def pick_LMB(self, event, index):
print "\nindex = " + str(index)
canvas = event.widget
x = canvas.canvasx(event.x)
width_x = 180.0
scaled_x = x/width_x * 100.0
print "scaled_x = " + '{0:.2f}'.format(scaled_x)
#entrys[index].delete(0, Tk.END)
#entrys[index].insert(0, '{0:.2f}'.format(scaled_x))
def pick_MMB(self, event):
canvas = event.widget
x = canvas.canvasx(event.x)
print "\nx = " + str(x)
width_x = 180.0
scaled_x = x/width_x * 100.0
print "scaled_x = " + '{0:.2f}'.format(scaled_x)
if __name__ == "__main__":
root = Tk.Tk()
Test(root)
root.mainloop()

I forgot the .create_image command, so it wasn't a problem with the reference after all.

Related

TypeError: get() missing 1 required positional argument: 'self' / Exception in Tkinter callback

So i've been working on this project and for some reason this error keeps poping up:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "D:\KPI\minesweeper\main.py", line 198, in login_verify
username_1 = username_verify.get()
TypeError: get() missing 1 required positional argument: 'self'
At first I've tried to combine .pack and grid in one class, but error occured, so I just put it off the class.
Then I tried to add this .pack piece of code to the new class, but there still was a problem.
TBO, this code kinda has different elements from different code, so i might've just got confused.
Here's a code:
from random import shuffle
from tkinter import *
from tkinter.messagebox import showinfo
import os
colors = {
0: 'white',
1: 'blue',
2: 'green',
3: 'red',
4: 'purple',
5: 'maroon',
6: 'turquoise',
7: 'black',
8: 'gray',
}
class Autherisation:
def __init__(self, master):
self.screen = screen
def delete2():
screen3.destroy()
def delete3():
screen4.destroy()
def delete4():
screen5.destroy()
def login_sucess():
global screen3
screen3 = Toplevel(screen)
screen3.title('Sucess')
screen3.geometry('150x100')
Label(screen3, text='Login sucess').pack()
Button(screen3, text='OK', command=delete2).pack()
def password_not_recognised():
global screen4
screen4 = Toplevel(screen)
screen4.title('Sucess')
screen4.geometry('150x100')
Label(screen4, text='Password not recognised').pack()
Button(screen4, text='OK', command=delete3).pack()
def user_not_found():
global screen5
screen5 = Toplevel(screen)
screen5.title('Sucess')
screen5.geometry('150x100')
Label(screen5, text='User not found').pack()
Button(screen5, text='OK', command=delete4).pack()
def register_user():
username_info = username_.get()
password_info = password_.get()
file = open(username_info, "w")
file.write(username_info + '\n')
file.write(password_info)
file.close()
username_entry.delete(0, END)
password_entry.delete(0, END)
Label(screen_1, text='Registration successful!', fg='green', font=('calibri', 11)).pack()
def login_verify():
username_1 = username_verify.get()
password_1 = password_verify.get()
username_entry1.delete(0, END)
password_entry1.delete(0, END)
list_of_files = os.listdir()
if username_1 in list_of_files:
file1 = open(username_1, 'r')
verify = file1.read().splitlines()
if password_1 in verify:
login_sucess()
else:
password_not_recognised()
else:
user_not_found()
def register():
global screen_1
screen_1 = Toplevel(screen)
screen_1.title("Register")
screen_1.geometry('300x250')
global username_
global password_
global username_entry
global password_entry
username_ = StringVar()
password_ = StringVar()
Label(screen_1, text='Please enter details below').pack()
Label(screen_1, text='').pack()
Label(screen_1, text='Username * ').pack()
username_entry = Entry(screen_1, textvariable=username_)
username_entry.pack()
Label(screen_1, text='Password * ').pack()
password_entry = Entry(screen_1, textvariable=password_)
password_entry.pack()
Button(screen_1, text='Register', width=10, height=1, command=register_user).pack()
def login():
global screen_2
screen_2 = Toplevel(screen)
screen_2.title("Login")
screen_2.geometry('300x250')
Label(screen_2, text='Please enter details below to login').pack()
Label(screen_2, text='').pack()
global username_verify
global password_verify
username_verify = StringVar
password_verify = StringVar
global username_entry1
global password_entry1
Label(screen_2, text='Username * ').pack()
username_entry1 = Entry(screen_2, textvariable=username_verify)
username_entry1.pack()
Label(screen_2, text='').pack()
Label(screen_2, text='Password * ').pack()
password_entry1 = Entry(screen_2, textvariable=password_verify)
password_entry1.pack()
Label(screen_2, text='').pack()
Button(screen_2, text='Login', width=10, height=1, command=login_verify).pack()
def login_screen():
global screen
screen = Tk()
screen.geometry("300x250")
screen.title("Minesweeper")
Label(text='MineSweeper', bg='grey', width='300', height='2', font=("calibri", 13)).pack()
Label(text='').pack()
Button(text='Login', height='2', width='30', command=login).pack()
Label(text='').pack()
Button(text="Register", height='2', width='30', command=register).pack()
screen.mainloop()
login_screen()
class MyButton(tk.Button):
def __init__(self, master, x, y, number=0, *args, **kwargs):
super(MyButton, self).__init__(master, width=3, font='Calibri 15 bold', *args, **kwargs)
self.x = x
self.y = y
self.number = number
self.is_mine = False
self.count_bomb = 0
self.is_open = False
def __repr__(self):
return f'MyButton{self.x} {self.y} {self.number} {self.is_mine}'
class MineSweeper:
window = tk.Tk()
window.title("MineSweeper")
row_ = 16
columns_ = 16
mines = 60
IS_GAME_OVER = False
IS_FIRST_CLICK = True
def __init__(self):
self.buttons = []
for i in range(MineSweeper.row_ + 2):
temp = []
for j in range(MineSweeper.columns_ + 2):
btn = MyButton(MineSweeper.window, x=i, y=j)
btn.config(command=lambda button=btn: self.click(button))
btn.bind('<Button-3>', self.right_click)
btn.bind('<Double-Button-1>', self.double_button_click)
temp.append(btn)
self.buttons.append(temp)
def right_click(self, event):
if MineSweeper.IS_GAME_OVER:
return
cur_btn = event.widget
if cur_btn['state'] == 'normal':
cur_btn['state'] = 'disabled'
cur_btn['text'] = '🚩'
cur_btn['disabledforeground'] = 'red'
elif cur_btn['state'] == '🚩':
cur_btn['text'] = ''
cur_btn['state'] = 'normal'
def double_button_click(self, event):
if MineSweeper.IS_GAME_OVER:
return
cur_btn = event.widget
if cur_btn['state'] == 'normal':
cur_btn['state'] = 'disabled'
cur_btn['text'] = '?'
cur_btn['disabledforeground'] = 'red'
elif cur_btn['state'] == '?':
cur_btn['text'] = ''
cur_btn['state'] = 'normal'
def click(self, clicked_button: MyButton):
if MineSweeper.IS_GAME_OVER:
return
if MineSweeper.IS_FIRST_CLICK:
self.insert_mines(clicked_button.number)
self.count_mines_in_buttons()
self.print_buttons()
MineSweeper.IS_FIRST_CLICK = False
print(clicked_button)
if clicked_button.is_mine:
clicked_button.config(text="*", background='red', disabledforeground='black')
clicked_button.is_open = True
MineSweeper.IS_GAME_OVER = True
showinfo('Game over', 'Вы проиграли!')
for i in range(1, MineSweeper.row_ + 1):
for j in range(1, MineSweeper.columns_ + 1):
btn = self.buttons[i][j]
if btn.is_mine:
btn['text'] = '*'
else:
color = colors.get(clicked_button.count_bomb, 'black')
if clicked_button.count_bomb:
clicked_button.config(text=clicked_button.count_bomb, disabledforeground=color)
clicked_button.is_open = True
else:
self.breadth_first_search(clicked_button)
clicked_button.config(state='disabled')
clicked_button.config(relief=tk.SUNKEN)
def breadth_first_search(self, btn: MyButton):
queue = [btn]
while queue:
cur_bth = queue.pop()
color = colors.get(cur_bth.count_bomb, 'black')
if cur_bth.count_bomb:
cur_bth.config(text=cur_bth.count_bomb, disabledforeground=color)
else:
cur_bth.config(text='', disabledforeground=color)
cur_bth.is_open = True
cur_bth.config(state='disabled')
cur_bth.config(relief=tk.SUNKEN)
if cur_bth.count_bomb == 0:
x, y = cur_bth.x, cur_bth.y
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
# if not abs(dx - dy) == 1:
# continue
next_btn = self.buttons[x + dx][y + dy]
if not next_btn.is_open and 1 <= next_btn.x <= MineSweeper.row_ and 1 <= next_btn.y <= MineSweeper.columns_ and next_btn not in queue:
queue.append(next_btn)
def reload(self):
[child.destroy() for child in self.window.winfo_children()]
self.__init__()
self.create_widgets()
MineSweeper.IS_FIRST_CLICK = True
MineSweeper.IS_GAME_OVER = False
def create_username_login(self):
win_log_in = tk.Toplevel(self.window)
win_log_in.wm_title("Log in/sign in")
tk.Label(win_log_in, text='Login').grid(row=0, column=0)
login_entrys = tk.Entry(win_log_in)
login_entrys.grid(row=0, column=1, padx=20, pady=20)
tk.Label(win_log_in, text='Password').grid(row=1, column=0)
password_entrys = tk.Entry(win_log_in)
password_entrys.grid(row=1, column=1, padx=20, pady=20)
my_file = open('user.txt', 'w')
my_file.write('login_entry')
my_file.write('password_entry')
# with open("file.text", "r") as file:
# data = file.readlines()
# for line in data:
# word = line.split()
# print(word)
def create_widgets(self):
menubar = tk.Menu(self.window)
self.window.config(menu=menubar)
settings_menu = tk.Menu(menubar, tearoff=0)
settings_menu.add_command(label='Save')
settings_menu.add_command(label='Log in', command=self.create_username_login)
settings_menu.add_command(label='Start over', command=self.reload)
settings_menu.add_command(label='Finish', command=self.window.destroy)
menubar.add_cascade(label='File', menu=settings_menu)
settings_menu = tk.Menu(menubar, tearoff=0)
settings_menu.add_command(label='Novice')
settings_menu.add_command(label='Amateur')
settings_menu.add_command(label='Professional')
menubar.add_cascade(label='Mode', menu=settings_menu)
count = 1
for i in range(1, MineSweeper.row_ + 1):
for j in range(1, MineSweeper.columns_ + 1):
btn = self.buttons[i][j]
btn.number = count
btn.grid(row=i, column=j, stick='NWES')
count += 1
for i in range(1, MineSweeper.row_ + 1):
tk.Grid.rowconfigure(self.window, i, weight=1)
for j in range(1, MineSweeper.columns_ + 1):
tk.Grid.columnconfigure(self.window, i, weight=1)
def open_all_buttons(self):
for i in range(MineSweeper.row_ + 2):
for j in range(MineSweeper.columns_ + 2):
btn = self.buttons[i][j]
if btn.is_mine:
btn.config(text="*", background='red', disabledforeground='black')
elif btn.count_bomb in colors:
color = colors.get(btn.count_bomb, 'black')
btn.config(text=btn.count_bomb, foreground=color)
def start(self):
self.create_widgets()
# self.login_screen()
# self.open_all_buttons()
# self.create_username_login()
MineSweeper.window.mainloop()
def print_buttons(self):
for i in range(1, MineSweeper.row_ + 1):
for j in range(1, MineSweeper.columns_ + 1):
btn = self.buttons[i][j]
if btn.is_mine:
print("B", end='')
else:
print(btn.count_bomb, end='')
print()
def insert_mines(self, number: int):
index_mines = self.get_mines_places(number)
print(index_mines)
for i in range(1, MineSweeper.row_ + 1):
for j in range(1, MineSweeper.columns_ + 1):
btn = self.buttons[i][j]
if btn.number in index_mines:
btn.is_mine = True
def count_mines_in_buttons(self):
for i in range(1, MineSweeper.row_ + 1):
for j in range(1, MineSweeper.columns_ + 1):
btn = self.buttons[i][j]
count_bomb = 0
if not btn.is_mine:
for row_dx in [-1, 0, 1]:
for col_dx in [-1, 0, 1]:
neighbour = self.buttons[i + row_dx][j + col_dx]
if neighbour.is_mine:
count_bomb += 1
btn.count_bomb = count_bomb
#staticmethod
def get_mines_places(exclude_number: int):
indexes = list(range(1, MineSweeper.columns_ * MineSweeper.row_ + 1))
print(f" {exclude_number}")
indexes.remove(exclude_number)
shuffle(indexes)
return indexes[:MineSweeper.mines]
game = MineSweeper()
game.start()
Quick answer
On line 198, you do username_verify.get(), which normally is fine, assuming username_verify is a tk.StringVar. If we scroll down we can find the definition of username_verify as following
global username_verify
username_verify = StringVar
If looked at the documentation, it can be seen that a StringVar should be initialized like this
string_var = tk.StringVar(container, value, name)
You are missing the parentheses containing the information needed to construct the actual StrinVar. This means your username_verify is just a pointer to the class, and not an actual instance of said class.
more technical details
When creating an instance, python makes a self which contains the instance together with all the unique values to this method. A class is purely a template of the methods and attribute names. When creating a class method, you will see that you always make self the first argument. Python implicitly adds the self when calling the method to refer to the instance from where it was called. This self gives you access to the unique values of this instance. (there are a few exceptions to this, namely class methods and static methods, but for the sake of simplicity I will not cover these)
In your code, you did not create a new instance. This means that there is no memory space reserved, and self is never assigned. When you are calling the method get(), python expects self to be passed. Due to there being no instance, this argument is missing and results in your error.

How to change button colour back to original when clicked again

I'm trying to change the button colour to black when clicked then change it back to white when clicked again. I'm trying to make Game Of Life for a school project.
I tried if statements but it doesn't change back to white, maybe I missed something simple. Here is the code:
from tkinter import *
class GUI(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
master.title("Window") #Window title
self.pack()
master.geometry("1280x720") #Window size
self.button={}#Dictionary for buttons
self.create_button()
def create_button(self):
indexList =[i for i in range(1000)]
self._button = Button(self, bg='white')
print(self._button.cget('bg'))
xPos = 0
yPos = 0
for index in indexList:
if(yPos == 40):
xPos = xPos + 20
yPos = 0
if(xPos == 10):
yPos = 8
self._button = Button(self, height=2, width=4, command = lambda
i = index: self.changecolour(i))
self.button[index] = self._button
self._button.grid(row=xPos, column =yPos)
yPos = yPos + 1
def changecolour(self,index):
aList = []
for i in range(1000):
aList.append([i,0])
for i in aList:
if index == i[0]:
if 0 == i[1]:
self.button[index].configure(bg = 'black')
i[1] = 1
else:
self.button[index].configure(bg = 'white')
i[1] = 0
root = Tk()
game_gui = GUI(master=root)
game_gui.mainloop()
As you can see it changes the button colour to black and it should change it back to white when clicked again, but it seems to just ignore the if statement.
I think this is the problem:
aList is not a global list
aList is created in changecolour() as a local list each time the subroutine is run
this means that when you do i[1] = 1 or i[1] = 0 it only changes the local list- aList. When the subroutine is run again, a new aList is created as a new local list.
to solve the problem define aList in the main program and make it a global list:
from tkinter import *
class GUI(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
master.title("Window") #Window title
self.pack()
master.geometry("1280x720") #Window size
self.button={}#Dictionary for buttons
self.create_button()
def create_button(self):
indexList =[i for i in range(1000)]
self._button = Button(self, bg='white')
print(self._button.cget('bg'))
xPos = 0
yPos = 0
for index in indexList:
if(yPos == 40):
xPos = xPos + 20
yPos = 0
if(xPos == 10):
yPos = 8
self._button = Button(self, height=2, width=4, command = lambda
i = index: self.changecolour(i))
self.button[index] = self._button
self._button.grid(row=xPos, column =yPos)
yPos = yPos + 1
def changecolour(self,index):
#aList IS NO LONGER CREATED HERE
for i in range(1000):
aList.append([i,0])
for i in aList:
if index == i[0]:
if 0 == i[1]:
self.button[index].configure(bg = 'black')
i[1] = 1
else:
self.button[index].configure(bg = 'white')
i[1] = 0
global aList #MAKE IT A GLOBAL LIST
aList = [] #CREATE THE EMPTY aList LIST
root = Tk()
game_gui = GUI(master=root)
game_gui.mainloop()

Python Tkinter layout using pack()

I am new to Tkinter. I'd like to write simple program and organize it using pack() method. Here is my code:
import Tkinter as tk
from Tkinter import *
import xlrd, os, sys, json
class Main():
def __init__(self):
global col, col1
self.master = tk.Tk()
self.master.title("Zliczanie ilosci spraw")
self.master.minsize(width=800, height=600)
plik = 'Aktualnie wybrany plik to: ' + 'Rejestr'
text = Label(self.master, text = plik)
text.pack(pady = 20)
self.wyswietlanie()
def wyswietlanie(self):
'''Funkcja, ktora zlicza i wyswietla ilosc spraw pracownikow'''
policzone_1 = []
policzone_2 = []
z = 0
dzial1 = {
"Pracownik1": "PRAC1",
"Pracownik2": "PRAC2"}
dzial2 = {
"Pracownik12": "PRAC12",
"Pracownik22": "PRAC22"}
for nazw in dzial1:
x = dzial1[nazw] #nazwisko z pliku excela
nazwisko = 0
policzone_1.append((nazw, nazwisko))
for nazw in dzial2:
x = dzial2[nazw] #nazwisko z pliku excela
nazwisko = 0
policzone_2.append((nazw, nazwisko))
posortowane1 = sorted(policzone_1,key=lambda x:x[1], reverse=True)
posortowane2 = sorted(policzone_2,key=lambda x:x[1], reverse=True)
dzial3 = Label(self.master)
dzial3.pack(side = LEFT)
dzial4 = Label(self.master)
dzial4.pack(side = LEFT)
for i in posortowane1:
wynik = '%s: %s' % (i[0], i[1])
dzial1 = Label(self.master, text = wynik, font = "Verdana 10 bold")
dzial1.pack(in_ = dzial3, padx = 200)
for i in posortowane2:
wynik = '%s: %s' % (i[0], i[1])
dzial2 = Label(self.master, text = wynik)
dzial2.pack(in_ = dzial4, padx = 200)
def run(self):
self.master.mainloop()
glowne = Main()
glowne.run()
Result is as on image below:
Why dzial1 and dzial2 are in these places (far from "text")? How can I organize dzial1, dzial2 (set them closer to each other)?

tkinter - A toplevel class getting a value from the main/parent class?

Below is a program that solves quadratic equations and graphs them. I was wondering what i needed to put where the comment is located in the code in order to get a value a parent class (quadratics) and use it in a Toplevel class. Any help would be appreciated.
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
from tkinter import *
class home():
def __init__(self,master):
self.master = master
self.master.geometry('400x450')
self.master.title('Mathsolver')
Button(self.master, text='Quadratics', command = self.open_quadratics).pack()
def open_quadratics(self):
quadratics(Toplevel(self.master))
class quadratics():
def __init__(self, master):
self.master = master
self.vara = DoubleVar()
self.varb = DoubleVar()
self.varc = DoubleVar()
self.master.geometry("500x300")
self.master.title("Quadratic Equations")
Label(self.master, text="Enter coefficients of x below in the form ax² + bx + c = 0").grid(row=1,column=1)
Label(self.master, text="a:").grid(row=2,column=1)
Entry(self.master, textvariable = self.vara).grid(row=2,column=2)
Label(self.master, text="b:").grid(row=3,column=1)
Entry(self.master, textvariable = self.varb).grid(row=3,column=2)
Label(self.master, text="c:").grid(row=4,column=1)
Entry(self.master, textvariable = self.varc).grid(row=4,column=2)
Button(self.master, text="Solve", command = self.calculate_quadratic).grid(row=5,column=2)
Button(self.master, text='Graph', command = self.grapher, bg='green').grid(row=5,column=2)
def grapher(self):
quadratic_grapher(Toplevel(self.master))
def calculate_quadratic(self):
global x
a = self.vara.get()
b = self.varb.get()
c = self.varc.get()
mp = (-b) / 2 * a
y = a * mp**2 + b * mp + c
d = b**2-4*a*c
if d < 0:
Label(self.master, text="No Solution for %.0fx² + %.0fx + %.0f = 0" % (a, b, c,)).grid(row=6,column=1)
elif d == 0:
x = (-b+d**0.5/2*a)
Label(self.master, text="One Solution for %.0fx² + %.0fx + %.0f = 0" % (a, b, c,)).grid(row=7,column=1)
Label(self.master, text="x= %f" % x).grid(row=8,column=1)
else:
x1 = ((-b)+(((b*b)-(4*a*c))**0.5))/(2*a)
x2 = ((-b)-(((b*b)-(4*a*c))**0.5))/(2*a)
Label(self.master, text="Two Solutions for %.0fx² + %.0fx + %.0f = 0:" % (a, b, c)).grid(row=9,column=1)
Label(self.master, text="x = %f" % x1).grid(row=10,column=1)
Label(self.master, text="x = %f" % x2).grid(row=11,column=1)
Label(self.master, text="Line of Symmetry: x = %f" % mp).grid(row=12,column=1)
Label(self.master, text="Vertex = (%f, %f)" % (mp, y)).grid(row=13,column=1)
class quadratic_grapher(quadratics):
def __init__(self, master):
self.master = master
self.a_coefficient = #what needs to be here to get the vara, varb and varc values in the quadratics class?
self.b_coefficient =
self.c_coefficient =
f = Figure(figsize=(5,4), dpi=100)
a = f.add_subplot(111)
self.x1 = []
self.y1 = []
self.x2 = []
self.y2 = []
self.x_positive_increment = 1
self.x_negative_decrement = -1
self.x_positive = 0
self.x_negative = 0
for plotPoints in range(0, 10):
self.y_positive = self.a_coefficient * self.x_positive**2 + self.b_coefficient * self.x_positive + self.c_coefficient
self.y_negative = self.a_coefficient * self.x_negative**2 + self.b_coefficient * self.x_negative + self.c_coefficient
self.x1.append(self.x_positive)
self.x2.append(self.x_negative)
self.y1.append(self.y_positive)
self.y2.append(self.y_negative)
self.x_positive = self.x_positive + self.x_positive_increment
self.x_negative = self.x_negative + self.x_negative_decrement
a.plot(self.x1, self.y1)
a.plot(self.x2, self.y2)
self.canvas = FigureCanvasTkAgg(f, master=master)
self.canvas.show()
self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
self.toolbar = NavigationToolbar2TkAgg(self.canvas, master )
self.toolbar.update()
self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)
def main():
root = Tk()
home(root)
root.mainloop()
if __name__ == '__main__':
main()
Unlike some other languages - python does not automatically call the constructor of the super classes, so you will need your quadratic_grapher class to explicitly call the constructor of the quadratics class :
Put this on the first line of your init method of your quadratic_grapher class
super(quadratic_grapher, self).__init__(master)
and now - since quadratic_grapher is also an instance of quadratic you can access the variables just by using self - so your commented lines become :
self.a_coefficient = self.vara
self.b_coefficient = self.varb
self.c_coefficient = self.varc

Using Tkinter to program an application need add buttons with same function. How to identify which button I clicked and change the line automatically?

The following things I want is to add multiple different tasks, and there is a task start button which is used to trig a timer.
class Pomodoro_app(Tk):
def add_task(self):
global time
time = StringVar()
time.set("Start")
task_content = askstring(title = 'Add a Task', prompt = "Input a task")
task_label = Label(self, text = task_content, font = ("Arial, 12")).grid(column = 0, row = 3)
task_start_button = Button(self, textvariable = time, command = self.start_working).grid(column = 1, row = 3)
def createWidgets(self):
self.welcome_label = Label(self, text = "Welcome to the Challenge!", font = ("Arial, 12")).grid(column = 0, row = 0, columnspan = 2)
self.add_task_button = Button(self, text = "Add Task", width = 20, command = self.add_task).grid(column = 0 , columnspan = 2)
def __init__(self):
"""GUI Initiation"""
Tk.__init__(self)
self.createWidgets()
"""window Initiation"""
self.resizable(False, False)
x = (self.winfo_screenwidth() - self.winfo_reqwidth()) / 2
y = (self.winfo_screenheight() - self.winfo_reqheight()) / 2
self.geometry('250x400+%d+%d' % (x, y))
Using lambda (or inner function), you can pass additional argument to callback.
For example:
class Pomodoro_app(Tk):
def add_task(self):
global time
time = StringVar()
time.set("Start")
task_content = askstring(title = 'Add a Task', prompt = "Input a task")
task_label = Label(self, text = task_content, font = ("Arial, 12")).grid(column = 0, row = self.next_row)
task_start_button = Button(self, textvariable = time, command = lambda: self.start_working(task_content)).grid(column = 1, row = self.next_row)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
self.next_row += 1
def start_working(self, task_name):
print('start working', task_name)
def createWidgets(self):
self.welcome_label = Label(self, text = "Welcome to the Challenge!", font = ("Arial, 12")).grid(column = 0, row = 0, columnspan = 2)
self.add_task_button = Button(self, text = "Add Task", width = 20, command = self.add_task).grid(column = 0 , columnspan = 2)
def __init__(self):
"""GUI Initiation"""
Tk.__init__(self)
self.createWidgets()
"""window Initiation"""
self.resizable(False, False)
x = (self.winfo_screenwidth() - self.winfo_reqwidth()) / 2
y = (self.winfo_screenheight() - self.winfo_reqheight()) / 2
self.geometry('250x400+%d+%d' % (x, y))
self.next_row = 3

Categories

Resources