Hello, sorry for the rudeness for asking for help on the first post but I'm still a beginner in programming.
I am trying to create a GUI for plotting function using Tkinter and Python. In the top a label will show the current position of the mouse in the canvas and the position of the last click in the canvas. I am learning classes at uni so I need to learn how to use it.
Whenever the label changes, instead of it staying in the top, a new window opens up with the details.
from Tkinter import *
def Click(event):
root = Tk()
x, y = event.x, event.y
PointFrame(root).Clicked(x, y)
def Move(event):
root = Tk()
x, y = event.x, event.y
PointFrame(root).Moved(x, y)
class PointFrame(object):
def __init__(self, root):
self._root = root
CoordRow = Frame(root)
CoordRow.grid(column=0, row=0)
self._LastPointLabel = Label(CoordRow)
self._LastPointLabel.pack(side=LEFT)
self._CurrentCoordLabel = Label(CoordRow)
self._CurrentCoordLabel.pack(side=RIGHT)
def Clicked(self, x, y):
self._x = x
self._y = y
self._LastPointLabel.config(text = 'Last Point Clicked: (' + str(self._x) + ',' + str(self._y) + ')')
def Moved(self, x, y):
self._x = x
self._y = y
self._CurrentCoordLabel.config(text = 'Cursor Point: (' + str(self._x) + ',' + str(self._y) + ')')
class FunctionFrame(object):
def __init__(self, root):
self._root = root
FunctionRow = Frame(root, relief=SUNKEN)
FunctionRow.grid(column=0, row=2)
g1 = Label(FunctionRow, text='Function in X: ')
g1.pack(side=LEFT)
FunctionInXInput = Entry(FunctionRow, width=35)
FunctionInXInput.pack(side=LEFT)
h1 = Label(FunctionRow, text=' Function Colour: ')
h1.pack(side=LEFT)
FunctionColourInput = Entry(FunctionRow, width=20)
FunctionColourInput.pack(side=LEFT)
space = Label(FunctionRow, text=' ')
space.pack(side=LEFT)
i1 = Button(FunctionRow, text='Select', padx = 5, command = CreateFunction())
i1.pack(side=RIGHT)
class PlotFrame(object):
def __init__(self, root):
self._root = root
PlotRow = Frame(root, relief=SUNKEN)
PlotRow.grid(column=0, row=3, pady=20)
a = Label(PlotRow, text='Plot Settings ')
a.pack(side=LEFT)
b1 = Label(PlotRow, text='Start X: ')
b1.pack(side=LEFT)
StartXInput = Entry(PlotRow, width=10)
StartXInput.pack(side=LEFT)
c1 = Label(PlotRow, text=' End X: ')
c1.pack(side=LEFT)
EndXInput = Entry(PlotRow, width=10)
EndXInput.pack(side=LEFT)
d1 = Label(PlotRow, text=' Start Y: ')
d1.pack(side=LEFT)
StartYInput = Entry(PlotRow, width=10)
StartYInput.pack(side=LEFT)
e1 = Label(PlotRow, text=' End Y: ')
e1.pack(side=LEFT)
EndYInput = Entry(PlotRow, width=10)
EndYInput.pack(side=LEFT)
f1 = Label(PlotRow, text=' Steps: ')
f1.pack(side=LEFT)
StepsInput = Entry(PlotRow, width=10)
StepsInput.pack(side=LEFT)
class PlotApp(object):
def __init__(self, root):
self._root = root
PlotFrame(root)
FunctionFrame(root)
PointFrame(root)
self.CreateCanvas()
def CreateCanvas(self):
canvas = Canvas(self._root, bg='White')
canvas.grid(column=0, row=1, sticky=(N, W, E, S))
canvas.bind("<Button-1>", Click)
canvas.bind("<Enter>", Move)
def CreateFunction():
pass
def main():
root = Tk()
app = PlotApp(root)
root.mainloop()
if __name__ == '__main__':
main()
Also could anyone tell me how to find current coordinates of mouse? Right now its if it enters the canvas.
Thanks and I hope to contribute in this site more in the future!
First I do not get why you have three calls to Tk in your code instead of regular one.
I had a feeling that it was wrong but if I remove both of the root = Tk() at the top, the following error message appears :global name 'root' is not defined
Nice approach.
However, opening a potentially endless amount of windows is terribly resource demanding. I would suggest to put the mouse info into the title bar of the root window ...
# PlottingProgram101.py
try:
# Python2
import Tkinter as tk
except ImportError:
# Python3
import tkinter as tk
class FunctionFrame(object):
def __init__(self, root):
self._root = root
functionRow = tk.Frame(root, relief='sunken')
functionRow.grid(column=0, row=2)
g1 = tk.Label(functionRow, text='Function in X: ')
g1.pack(side='left')
functionInXInput = tk.Entry(functionRow, width=35)
functionInXInput.pack(side='left')
h1 = tk.Label(functionRow, text=' Function Colour: ')
h1.pack(side='left')
functionColourInput = tk.Entry(functionRow, width=20)
functionColourInput.pack(side='left')
space = tk.Label(functionRow, text=' ')
space.pack(side='left')
b1 = tk.Button(functionRow, text='Select', padx=5,
command=createFunction())
b1.pack(side='right')
class PlotFrame(object):
def __init__(self, root):
self._root = root
plotRow = tk.Frame(root, relief='sunken')
plotRow.grid(column=0, row=3, pady=20)
a = tk.Label(plotRow, text='Plot Settings ')
a.pack(side='left')
b1 = tk.Label(plotRow, text='Start X: ')
b1.pack(side='left')
startXInput = tk.Entry(plotRow, width=10)
startXInput.pack(side='left')
c1 = tk.Label(plotRow, text=' End X: ')
c1.pack(side='left')
endXInput = tk.Entry(plotRow, width=10)
endXInput.pack(side='left')
d1 = tk.Label(plotRow, text=' Start Y: ')
d1.pack(side='left')
startYInput = tk.Entry(plotRow, width=10)
startYInput.pack(side='left')
e1 = tk.Label(plotRow, text=' End Y: ')
e1.pack(side='left')
endYInput = tk.Entry(plotRow, width=10)
endYInput.pack(side='left')
f1 = tk.Label(plotRow, text=' Steps: ')
f1.pack(side='left')
stepsInput = tk.Entry(plotRow, width=10)
stepsInput.pack(side='left')
class PlotApp(object):
def __init__(self, root):
self._root = root
PlotFrame(root)
FunctionFrame(root)
self.createCanvas()
def createCanvas(self):
canvas = tk.Canvas(self._root, bg='white')
canvas.grid(column=0, row=1, sticky='nwes')
canvas.bind("<Button-1>", self.clicked)
canvas.bind("<Enter>", self.moved)
def clicked(self, event):
x, y = event.x, event.y
s = "Last point clicked at x=%s y=%s" % (x, y)
self._root.title(s)
def moved(self, event):
x, y = event.x, event.y
s = "Cursor at x=%s y=%s" % (x, y)
self._root.title(s)
def createFunction():
pass
def main():
root = tk.Tk()
app = PlotApp(root)
root.mainloop()
if __name__ == '__main__':
main()
Also, some housekeeping:
1) don't start a variable name with a capital letter, use those for class names
2) avoid variable names like i1, l, l1 and the like
3) try to keep the tkinter name space with 'tk.'
As your program gets larger, you and others will appreciate this.