-1

在两个 stackoverflow 用户的大力帮助下,我编写了这段代码。它是应该从 GCODE(3D 打印机创建对象的代码)中提取使用的灯丝值的代码。到目前为止,它运行良好,并且该值根据我的需要显示在 tkinter 窗口中。问题是这个值表示所用灯丝的体积。现在我想在 tkinter 窗口中计算和显示另外两个值 1)质量,volume*1,13然后是新发现的价格mass*0.175。问题是我无法弄清楚如何使用 gcode 中的这个值并使其可用于计算。self.value是从加载的文件中找到的初始变量(这里我附上示例 gcode 文件,您可以使用它来测试代码:smaple gcode)。我认为问题在于这个值是一个字符串,它应该是一个整数,以便在他的代码中进行计算我试图将它更改为整数,但它没有工作,所以我已经注释掉了。非常感谢您提供所有可能的提示和帮助。

PS Additionaly 我想在上传文件后更改状态栏,我也遇到了问题。

完整代码:

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))

        volume = self.get_filament_value(root.fileName)
        mass = volume * 1.13
        price = mass * 0.175

        self.volume_text.set('Volume is {}'.format(volume))
        self.mass_text.set('Mass is {}'.format(mass))
        self.price_text.set('Price is {}'.format(price))

    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
        l_instruction = Label(self, justify=CENTER, compound=TOP, text="Load GCODE file to find volume, \n weight and price of used filament.")
        l_instruction.pack()


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

        #Label of the used filament

        l1 = Label(self, text="")
        l1.pack()
        l2 = Label(self, text="")
        l2.pack()

        self.volume_text = StringVar()
        l = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.volume_text)
        l.pack()

        self.mass_text = StringVar()
        m = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.mass_text)
        m.pack()

        self.price_text = StringVar()
        p = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.price_text)
        p.pack()


        #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()

这是我得到的错误:

Traceback (most recent call last):
  File "/Users/domagalski/Desktop/test.py", line 112, in <module>
    app = Window(root)
  File "/Users/domagalski/Desktop/test.py", line 20, in init
    self.init_window()
  File "/Users/domagalski/Desktop/test.py", line 95, in init_window
    self.mass = self.value(self.get_filament_value(root.fileName))
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.‌​py", line 1939, in getattr
    return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'fileName'
4

1 回答 1

0

在您的init_window方法中,您尝试访问root.fileName

def init_window(self):
    # ...
    self.mass = self.value.set(self.get_filament_value(root.fileName))
    # ...

root.fileName设置在read_gcode

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

read_gcode仅在用户单击按钮时才被调用:

gcodeButton = Button(self, text="Load GCODE", command=self.read_gcode)

因为您需要用户单击加载 GCODE按钮才能获取文件名,所以您应该self.mass = ...从 : 中删除代码,init_windowinit_window被调用时,root.fileName尚不可用。将该代码移入read_gcode.

您遇到的另一个问题是您正在分配self.mass由返回的值self.value.set(),即None. 您应该改用来自 的返回值self.get_filament_value()

换句话说,改变这个:

def get_filament_value(self, fileName):
    # ...
        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))

def init_window(self):
    # ...

    self.value = StringVar()
    l = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.value)
    l.pack()

    # self.mass = self.value.set(self.get_filament_value(root.fileName))
    # int(self.mass)
    # m = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.mass)
    # m.pack()

    # ...

对此:

def get_filament_value(self, fileName):
    # ...
        if re_value:
            return float(re_value.group(1))
        else:
            return 0.0

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

    volume = self.get_filament_value(root.fileName)
    mass = volume * 1.13

    self.volume_text.set('Volume is {}'.format(volume))
    self.mass_text.set('Mass is {}'.format(mass))

def init_window(self):
    # ...
    self.volume_text = StringVar()
    self.mass_text = StringVar()

    volume_label = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.volume_text)
    volume_label.pack()

    mass_label = Label(self, justify=CENTER, compound=BOTTOM, textvariable=self.mass_text)
    mass_label.pack()
    # ...
于 2016-01-11T11:24:16.867 回答