简体   繁体   中英

How to display the variable in a tkinter window?

I am completely new to Python and I am working on a following code that I made with big help of fellow stackflow user.

After running the script a tkinter window open where you can select a gcode file (it is a file with many many lines of instructions for a 3D printer) and later a specific value from this file is found.

What I would like to achieve is to:

1) Display this value under the load GCODE button in a tkinter window with a description/label.

2) Make some calculations on this value and display them in the tkinter window too.

3) Finaly make an executable of this script so everyone can use it, even without Python installed.

I am not sure if this is super easy or it's a lot of work as I am completely new to Python (and not so good in programming overall). I hope I have explained things good enough and thank you in advance for any input!

Gcode file for code testing: GCODE FILE

Finaly the code:

from tkinter import *
import re
from tkinter import messagebox
from tkinter import filedialog

# Here, we are creating our class, Window, and inheriting from the Frame
# class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__)
class Window(Frame):

    # Define settings upon initialization. Here you can specify
    def __init__(self, master=None):

        # parameters that you want to send through the Frame class. 
        Frame.__init__(self, master)   

        #reference to the master widget, which is the tk window                 
        self.master = master

        #with that, we want to then run init_window, which doesn't yet exist
        self.init_window()

    # Load the gcode file in and extract the filament value
    def get_filament_value(self, fileName):
        with open(fileName, 'r') as f_gcode:
            data = f_gcode.read()
            re_value = re.search('filament used = .*? \(([0-9.]+)', data)

            if re_value:
                value = float(re_value.group(1))
                return('Volume of the print is {} cm3'.format(value))
            else:
                value = 0.0
                return('Filament volume was not found in {}'.format(fileName))
        return value

    def read_gcode(self):
        root.fileName = filedialog.askopenfilename(filetypes = (("GCODE files", "*.gcode"), ("All files", "*.*")))
        self.value.set = self.get_filament_value(root.fileName)
#       self.value.set('Button pressed')

    def client_exit(self):
        exit()

    def about_popup(self):
        messagebox.showinfo("About", "Small software created by Bartosz Domagalski to find used filament parameters from Sli3er generated GCODE")

    #Creation of init_window
    def init_window(self):

        # changing the title of our master widget      
        self.master.title("Filament Data")

        # allowing the widget to take the full space of the root window
        self.pack(fill=BOTH, expand=1)

        # creating a menu instance
        menu = Menu(self.master)
        self.master.config(menu=menu)

        # create the file object)
        file = Menu(menu)
        help = Menu(menu)

        # adds a command to the menu option, calling it exit, and the
        # command it runs on event is client_exit
        file.add_command(label="Exit", command=self.client_exit)
        help.add_command(label="About", command=self.about_popup)

        #added "file" to our menu
        menu.add_cascade(label="File", menu=file)
        menu.add_cascade(label="Help", menu=help)


        #Creating the labels
        self.value = StringVar()
        l_instruction = Label(self, justify=CENTER, compound=TOP, text="Load GCODE file to find volume, \n weight and price of used filament.")
        l = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.value)
#       l.place(x=85, y=45)
        l_instruction.pack()
        l.pack()

        #Creating the button
        gcodeButton = Button(self, text="Load GCODE", command=self.read_gcode)
        gcodeButton.pack()
#       gcodeButton.place(x=140, y=10)

        #status Bar
        status = Label(self, text="Waiting for file...", bd=1, relief=SUNKEN, anchor=W)
        status.pack(side=BOTTOM, fill=X)

# root window created. Here, that would be the only window, but you can later have windows within windows.
root = Tk()
root.resizable(width=False,height=False);
root.geometry("220x300")


#creation of an instance
app = Window(root)

#mainloop 
root.mainloop()

You should put the Label(s) inside the same Frame as you have the button. And when I copied in your code I had to import the filedalog module as well ( from tkinter import filedalog ), the asterisk import didn't seem to cover it.

You could use a StringVar() variable (from tkinter) and assign it to the label. This variable you can .set() and .get() values from. Create variable and assign it to Label:

self.value = StringVar('', value="  Load GCODE file to find volume, \n weight and price of used filament.")
l = Label(self, textvariable=self.value)

Alter variable value:

self.value.set(self.get_filament_value(root.fileName))

The Label you will have to place as you want it, just like you did with the Button with quitButton.place . There are other ways to handle the layout, grid and pack. But as far as I know, it is recommended to pick one layout style for all elements.

Creating an executable, "freezing" your code, is a broader topic. Take a look here for some options that you can look more into.


edit:

Updated working code. Changing the placement of widgets you'll figure out ;) Not looked at any new elements in your code.

from tkinter import *
import re
from tkinter import messagebox, filedialog


# Here, we are creating our class, Window, and inheriting from the Frame
# class. Frame is a class from the tkinter module. (see Lib/tkinter/__init__)
class Window(Frame):
    # Define settings upon initialization. Here you can specify
    def __init__(self, master=None):

        # parameters that you want to send through the Frame class.
        Frame.__init__(self, master)

        # reference to the master widget, which is the tk window
        self.master = master

        # with that, we want to then run init_window, which doesn't yet exist
        self.init_window()

    # Load the gcode file in and extract the filament value
    def get_filament_value(self, fileName):
        with open(fileName, 'r') as f_gcode:
            data = f_gcode.read()
            re_value = re.search('filament used = .*? \(([0-9.]+)', data)

            if re_value:
                value = float(re_value.group(1))
                return 'Volume of the print is {} cm3'.format(value)
            else:
                return 'Filament volume was not found in {}'.format(fileName)

    def read_gcode(self):
        root.fileName = filedialog.askopenfilename(filetypes=(("GCODE files", "*.gcode"), ("All files", "*.*")))
        self.value.set(self.get_filament_value(root.fileName))

    def client_exit(self):
        exit()

    def about_popup(self):
        messagebox.showinfo("About",
                            "Small software created by Bartosz Domagalski to find used filament parameters from Sli3er generated GCODE")

    # Creation of init_window
    def init_window(self):

        # changing the title of our master widget
        self.master.title("Filament Data")

        # allowing the widget to take the full space of the root window
        self.pack(fill=BOTH, expand=1)

        # creating a menu instance
        menu = Menu(self.master)
        self.master.config(menu=menu)

        # create the file object)
        file = Menu(menu)
        help = Menu(menu)

        # adds a command to the menu option, calling it exit, and the
        # command it runs on event is client_exit
        file.add_command(label="Exit", command=self.client_exit)
        help.add_command(label="About", command=self.about_popup)

        # added "file" to our menu
        menu.add_cascade(label="File", menu=file)
        menu.add_cascade(label="Help", menu=help)

        # Creating the labels
        self.value = StringVar()
        l_instruction = Label(self, justify=CENTER, compound=TOP,
                              text="  Load GCODE file to find volume, \n weight and price of used filament.")
        l = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.value)
        #       l.place(x=85, y=45)
        l_instruction.pack()
        l.pack()

        l_instruction.pack()
        self.value = StringVar()
        l = Label(self, textvariable=self.value)
        l.pack()

        # Creating the button
        gcodeButton = Button(self, text="Load GCODE", command=self.read_gcode)
        gcodeButton.pack()
        #       gcodeButton.place(x=140, y=10)

        # status Bar
        status = Label(self, text="Waiting for file...", bd=1, relief=SUNKEN, anchor=W)
        status.pack(side=BOTTOM, fill=X)


# root window created. Here, that would be the only window, but you can later have windows within windows.
root = Tk()
root.resizable(width=False, height=False);
# root.geometry("400x300")


# creation of an instance
app = Window(root)

# mainloop
root.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM