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!

Recommended Answers

All 5 Replies

First I do not get why you have three calls to Tk in your code instead of regular one.

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.

commented: agree muchly +13

Really nice site. Spent 3 minutes to remove all of the numbers from the left side of the source code after pasting the text. :D

Double click on the source code and it will highlight. Then copy and paste without the line numbers.

commented: double click and Ctrl-C work for me +14
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.