【问题标题】:How to display the variable in a tkinter window?如何在 tkinter 窗口中显示变量?
【发布时间】:2016-01-07 14:58:41
【问题描述】:

我对 Python 完全陌生,我正在编写以下代码,该代码是在其他 stackflow 用户的大力帮助下编写的。

运行脚本后,将打开一个 tkinter 窗口,您可以在其中选择一个 gcode 文件(它是一个包含许多多行 3D 打印机指令的文件),然后从该文件中找到一个特定值。

我想要实现的是:

1) 在带有描述/标签的 tkinter 窗口中的加载 GCODE 按钮下显示此值。

2) 对该值进行一些计算,并将它们也显示在 tkinter 窗口中。

3) 最后制作这个脚本的可执行文件,这样每个人都可以使用它,即使没有安装 Python。

我不确定这是否超级简单,或者因为我对 Python 完全陌生(而且整体编程不太好),所以需要做很多工作。我希望我已经解释得足够好,并提前感谢您的任何意见!

用于代码测试的Gcode文件:GCODE FILE

最后是代码:

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

【问题讨论】:

    标签: python user-interface tkinter g-code


    【解决方案1】:

    您应该将Label(s) 放在与按钮相同的Frame 中。当我复制你的代码时,我还必须导入filedalog 模块(from tkinter import filedalog),星号导入似乎没有涵盖它。

    您可以使用 StringVar() 变量(来自 tkinter)并将其分配给标签。这个变量你可以从.set().get() 取值。创建变量并将其分配给标签:

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

    改变变量值:

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

    您必须按照自己的意愿放置标签,就像使用带有quitButton.place 的按钮一样。还有其他处理布局、网格和包的方法。但据我所知,建议为所有元素选择一种布局样式。

    创建可执行文件,“冻结”您的代码,是一个更广泛的话题。联系look here 了解一些您可以深入研究的选项。


    编辑:

    更新的工作代码。更改小部件的位置,您会发现 ;) 没有查看代码中的任何新元素。

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

    【讨论】:

    • 您好,感谢您的回答,我尝试按照您的建议实现它,但没有好的结果(我已经更新了主要问题中的代码)。我不确定这个filedalog 模块,因为当我编译时我没有提示。也谢谢你的链接,我会在代码准备好后查看它。
    • 我注意到标签上有错字,使用 root 作为父级而不是 self。解决了这个问题。还添加了放入代码中时的外观。
    • 好的,我正在慢慢理解这一点。因此,您使用硬编码的“按下按钮”消息的示例有效。但我仍然无法显示从 gcode 文件中找到的值。最重要的是,我意识到这样新消息(在您的示例中为“按下按钮”)显示在标签顶部并且该标签消失了。我想要实现的是,在 gcode 加载后,值显示在按钮下方的 tkinter 窗口中,而不是标签。我希望我的解释足够清楚;)
    • 我已将代码更新到最新版本,您也可以下载 gcode 文件进行测试。谢谢大家的帮助!
    • 为了进一步澄清,当您使用按钮并在 shell 中上传 gcode 文件时,您会收到以下消息:Volume of the print is 19.5 cm3,我希望此消息在 tkinter 窗口中显示为上传 GCODE 按钮下方的新元素。
    猜你喜欢
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    • 2019-03-04
    • 2016-05-10
    • 2021-07-04
    • 2018-01-08
    相关资源
    最近更新 更多