关于tkinter combobox取值的问题

问题遇到的现象和发生背景

我在尝试做一个计算器,其中建立了一个combobox.以下是它的代码

from tkinter import *
from tkinter.ttk import *
class WinGUI(Tk):
    def __init__(self):
        super().__init__()
        self.__win()
        self.label_frame_feature = Frame_feature(self)
        self.level = ""
    def get_level(self):
        self.level = self.label_frame_feature.select_box_level[1] #用了这个[1],麻烦帮我看一下下
        return self.level
    def set_level(self,level):
        self.level = level
    def __win(self):
        self.title("Heat Loss Calculator")
     ----snip----
class Frame_feature(LabelFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.__frame()
        self.select_box_level = self.select_box_level()
    ----snip----
    def select_box_level(self):
        self.var = StringVar()
        self.cb = Combobox(self, state="readonly",textvariable=self.var)
        self.cb['values'] = ("Ground floor","Intermediated level","Top floor")
        self.cb.place(x=10, y=40, width=150, height=24)
        return self.cb, self.cb.get()
然后我在另一个模块中调用了以上这个类,以下是event.py
rom tkinter import *
from tkinter.ttk import *
from tkinter_helper import WinGUI

class Win():
    def __init__(self,win_gui_instance):
        self.win_gui = win_gui_instance
        self.__event_bind()

    #only a pure method
    def calc_level(self):
        self.level = self.win_gui.get_level()
        if self.level == "Intermediated level":
            self.level = 0   
        elif self.level == "Ground floor":
            self.level = 1
        else:
            self.level =0.7 #这里
        return self.level

    def update_level(self,level):   
        new_level = self.calc_level()
        self.win_gui.set_level(new_level)
        return print(self.win_gui.level),

    def __event_bind(self):
        self.win_gui.button_calcNow.bind('',self.update_level)

root = WinGUI() 
win = Win(root)
root.mainloop()
运行结果及详细报错内容

理论上,选combobox不同的内容会有对应的值,但是现在只会返回0.7。也就是说self.win_gui.get_level() 为空,我尝试打印了该值,确认为空。请问为什么会这样呢

0.7
0.7
0.7
[Finished in 4.1s]

估计你获取combbox的取值方法不对啊。

def selection(event):
    # combobox的三种取值方法
    print(event.widget.get())
    print(combo.get())
    print(combo_var.get())
combo = ttk.Combobox(root, values=values, textvariable=combo_var)
combo.pack()
combo.bind("<<ComboboxSelected>>",  selection)

所以你那里要修改为
self.level=...(select_box_level()[0]).get()

我看起来你提供的代码是一个使用Python中tkinter库的GUI的有效实现。但是,有几个问题你可能希望解决,以改进代码:
在'Win'类中,在'update_level'方法中,看起来是'print(self.win_gui.level)'行缩进错误.它应该在'return'语句之外,否则它将不会被执行
在'Win'类中,在'calc_level'方法中,最后一个else语句的主体将值0.7分配给self.level.可能有助于添加解释为什么的注释.此外,为了提高代码的可读性和可维护性,你可能需要考虑以下事项:
使用更有意义的变量名和函数名,例如更改“__win”和“__frame”为“initialize_window”和“initialize_frame”等。
使用更详细的注释解释代码的用途和工作原理。
将相关的代码分组到不同的函数或类中,以便更容易地管理和维护。
总之,你提供的代码似乎是一组可工作的组件,但可能需要进一步改进来提高代码的可读性,可维护性和可扩展性。例如,你可以考虑使用类和对象来封装代码,并使用继承和多态来重用代码。此外,你可以考虑使用更多的第三方库和模块来简化代码,并使用单元测试来验证代码的正确性。希望这对你有所帮助!
这是一个简单的修改代码的例子:

from tkinter import *
from tkinter.ttk import *

class WinGUI(Tk):
    def __init__(self):
        super().__init__()
        self.title("Heat Loss Calculator")
        self.label_frame_feature = Frame_feature(self)
        self.level = ""
    def get_level(self):
        return self.label_frame_feature.select_box_level.get()
    def set_level(self,level):
        self.label_frame_feature.select_box_level.set(level)

class Frame_feature(LabelFrame):
    def __init__(self,parent):
        super().__init__(parent)
        self.__frame()
        self.select_box_level = self.select_box_level()
    def __frame(self):
        self.config(text="Feature")
        self.pack(padx=10, pady=10
def select_box_level(self):
    self.var = StringVar()
    self.cb = Combobox(self, state="readonly",textvariable=self.var)
    self.cb['values'] = ("Ground floor","Intermediated level","Top floor")
    self.cb.place(x=10, y=40, width=150, height=24)
    return self.cb
class Win():
def init(self,win_gui_instance):
self.win_gui = win_gui_instance
self.__event_bind()
def update_level(self,event):
level = self.win_gui.get_level()
if level == "Intermediated level":
new_level = 0
elif level == "Ground floor":
new_level = 1
else:
new_level = 0.7
self.win_gui.set_level(new_level)
def __event_bind(self):
self.win_gui.button_calcNow.bind('<Button-1>',self.update_level)

root = WinGUI()
win = Win(root)
root.mainloop()

在这个例子中, 我们已经将 WinGUI 中的 get_levelset_level 方法重写为通过 self.label_frame_feature.select_box_level 直接读取和设置级别. 你可以删除 self.level = "" 变量,因为它不再需要了.

同样,在 Win 类中, 我们已经将 calc_level 方法更改为直接在 update_level 中计算新的级别,并将其设置为 win_gui.set_level(new_level).

此外,在绑定事件处理程序时,我们将事件处理程序函数的参数更改为在绑定事件处理程序时,我们将事件处理程序函数的参数更改为 event,这是Tkinter的默认值,表示事件对象.

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632