如何处理Tkin中的标签覆盖

2024-09-30 22:10:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python和tkinter的新手,我正在尝试用它创建一个GUI。我正在尝试根据第一个组合框的选择创建新的标签和组合框。我已经完成了第一个可选组合框的创建,并基于在第一个组合框中选择的选项绑定了新标签和组合框的创建。你知道吗

但是,由于不同的选择会产生不同数量的标签和组合框,并且其中一些标签和组合框位于帧的相同位置,因此标签和组合框可能会相互重叠,从而导致用户阅读混乱。主要问题在'def createSystem(self,event)'函数中,因为这里使用了两个for循环,我不知道如何清除第一个'if条件'创建的旧标签/组合框,然后在程序满足第二个'if条件'时创建新标签/组合框。你知道吗

到目前为止,我尝试了两种解决方案,但都没有成功。你知道吗

  1. 我试图创建一个全局列表,并将在私有函数中创建的所有标签推入其中,这样我就可以使用标签.销毁()清除所有标签并创建新标签。但是,问题是我不知道如何将正在创建的标签添加到列表中,以及如何在第二个for循环开始创建新标签之前删除。

  2. 我曾想过直接修改特定行中现有标签的文本,但由于标签是使用函数的ttk.标签()'而不分配给任何变量,因此我无法对它们进行寻址和修改。如果我想把它们分配给不同的变量,我需要在for循环中同时创建变量,我在google上搜索过,这被认为是一件坏事,尽管在Python中是可行的。

import tkinter as tk
from tkinter import ttk


cc_category = {'zxcv': ["vzxcv"], 'qeqL': ["safx"]}

ab_type = ["sfda", "fsdf"]
bbbbList = {
               'sddd':["1","2","3","4"],
               'ssss sdddd':["1", "2", "3", "4", "5", "6", "2500", "4500"], 
               'assss sssaz':["BA", "BB", "BC", "BD", "BE", "BF", "BWD", "BWA"], 
               'asdf Cfsdfsddf':["1"], 
               'asdf fasdfs' :["1"], 
               'asdf zxxxxxx':["1"], 
               'cccc xxxxxxx':["1"], 
               'cccc saddddL':["1","2","4","42","2"], 
               'zxxx xvzzzzL':["1","2","3"], 
               'cvcv cccxxxc':["2","2","EPDM","3","3","4","4","82","122","333"], 
               }

aaaaLabelList = {'wwww':[], 
                     'qqqq':[], 
                     'hjfgjhk':[], 
                     'xzvxzcvx':[],
                     'qweaddddz':[], 
                     'qweasd':[],
                     'utyiuiufturt':[],
                     'zxcvxzbvc':[],
                     'fdass':[],
                     'ffdasdd':[], 
                     'fsdfaL':[],
                     'fdasfzxAL':[],
                     'fdsafdL':[],
                     'Dasdfszxd':[], 
                     'dasfsdfsadE':[],
                     'FIRE SAFE':[], 
                     'rrrr':[], 
                     'eeee':[]}

framelist = []
frames = 1
labellist = [20]

class Root (tk.Tk):
    def __init__(self):
        super(Root, self).__init__()
        self.title("sssssss")
        self.minsize(640, 400)
        self.InitUI()



    def getUpdateData(self, event):
        self.cb['values'] = cc_category[self.ValveTypeCombo.get()]



    def add_frame(self):
        global frames
        framelist.append(tk.Frame(root))
        framelist[-1].grid()
        frames += 1

    def delete_frame(self):
        global frames
        framelist.remove(tk.Frame(root))
        framelist[-1].detory()
        frames -= 1

    def createSystem(self, event):

        if self.labelCombo.get() == "zxcv":
            for labelname in bbbbList:   
                ttk.Label(self, text = labelname + ":     ").grid(column = 0, row = list(bbbbList).index(labelname) + 2) 
                ttk.Combobox(self, width = 10, state = 'readonly', values = bbbbList.get(labelname)).grid(column = 1, row = list(bbbbList).index(labelname) + 2)




        if self.labelCombo.get() == "qeqL":
            for labelname in aaaaLabelList:   
                ttk.Label(self, text = labelname + ":     ").grid(column = 0, row = list(aaaaLabelList).index(labelname) + 2) 
                ttk.Combobox(self, width = 10, state = 'readonly', values = aaaaLabelList.get(labelname)).grid(column = 1, row = list(aaaaLabelList).index(labelname) + 2)



    def InitUI(self):
        self.label_1 = ttk.Label(self,text = "asss dddd:    ")
        self.label_1.grid(column = 0, row = 0)


        self.labelCombo = ttk.Combobox(self, width = 5, state = 'readonly', values = list(cc_category.keys()))
        self.labelCombo.bind('<<ComboboxSelected>>', self.createSystem)

        self.labelCombo.grid(column = 1, row = 0)





if __name__== '__main__':
    root = Root()
    root.mainloop()

下面是我编写的代码,用于将在for循环中创建的标签传递到全局列表。但它有一个编译错误:

line 77, in createSystem
   labellist[i].grid(column = 0, row = list(bbbbList).index(labelname) + 2)
AttributeError: 'int' object has no attribute 'grid' 

我不知道该怎么处理。你知道吗

以下是我第一个不起作用的想法的完整代码:

import tkinter as tk
from tkinter import ttk


cc_category = {'zxcv': ["vzxcv"], 'qeqL': ["safx"]}

ab_type = ["sfda", "fsdf"]
bbbbList = {
               'sddd':["1","2","3","4"],
               'ssss sdddd':["1", "2", "3", "4", "5", "6", "2500", "4500"], 
               'assss sssaz':["BA", "BB", "BC", "BD", "BE", "BF", "BWD", "BWA"], 
               'asdf Cfsdfsddf':["1"], 
               'asdf fasdfs' :["1"], 
               'asdf zxxxxxx':["1"], 
               'cccc xxxxxxx':["1"], 
               'cccc saddddL':["1","2","4","42","2"], 
               'zxxx xvzzzzL':["1","2","3"], 
               'cvcv cccxxxc':["2","2","EPDM","3","3","4","4","82","122","333"], 
               }

aaaaLabelList = {'wwww':[], 
                     'qqqq':[], 
                     'hjfgjhk':[], 
                     'xzvxzcvx':[],
                     'qweaddddz':[], 
                     'qweasd':[],
                     'utyiuiufturt':[],
                     'zxcvxzbvc':[],
                     'fdass':[],
                     'ffdasdd':[], 
                     'fsdfaL':[],
                     'fdasfzxAL':[],
                     'fdsafdL':[],
                     'Dasdfszxd':[], 
                     'dasfsdfsadE':[],
                     'FIRE SAFE':[], 
                     'rrrr':[], 
                     'eeee':[]}

framelist = []
frames = 1
labellist = [20]

class Root (tk.Tk):
    def __init__(self):
        super(Root, self).__init__()
        self.title("sssssss")
        self.minsize(640, 400)
        self.InitUI()



    def getUpdateData(self, event):
        self.cb['values'] = cc_category[self.ValveTypeCombo.get()]



    def add_frame(self):
        global frames
        framelist.append(tk.Frame(root))
        framelist[-1].grid()
        frames += 1

    def delete_frame(self):
        global frames
        framelist.remove(tk.Frame(root))
        framelist[-1].detory()
        frames -= 1

    def createSystem(self, event):

        if self.labelCombo.get() == "zxcv":
            for i, labelname in zip(range(20),bbbbList):
                root.add_frame()
                labellist.append(tk.Frame(root))
                ttk.Label(framelist[i], text = labelname + ":     ")
                labellist[i].grid(column = 0, row = list(bbbbList).index(labelname) + 2) 
                ttk.Combobox(self, width = 10, state = 'readonly', values = bbbbList.get(labelname)).grid(column = 1, row = list(bbbbList).index(labelname) + 2)
                i += 1



        if self.labelCombo.get() == "qeqL":
            for labelname in aaaaLabelList:   
                ttk.Label(self, text = labelname + ":     ").grid(column = 0, row = list(aaaaLabelList).index(labelname) + 2) 
                ttk.Combobox(self, width = 10, state = 'readonly', values = aaaaLabelList.get(labelname)).grid(column = 1, row = list(aaaaLabelList).index(labelname) + 2)



    def InitUI(self):
        self.label_1 = ttk.Label(self,text = "asss dddd:    ")
        self.label_1.grid(column = 0, row = 0)


        self.labelCombo = ttk.Combobox(self, width = 5, state = 'readonly', values = list(cc_category.keys()))
        self.labelCombo.bind('<<ComboboxSelected>>', self.createSystem)

        self.labelCombo.grid(column = 1, row = 0)





if __name__== '__main__':
    root = Root()
    root.mainloop()

我希望在切换第一个组合框中选择的值时,标签和组合框不会相互重叠,能够访问所有新创建的组合框中选择的值以供进一步使用。例如,我可以创建一个submit按钮来提交在选择第一个组合框之后创建的组合框中选择的所有值。你知道吗

编辑

我已经编辑了createSystem函数,现在可以编译了,但问题是似乎一直在向“framelist[]”添加标签,我试图在for循环中添加“framelist[I].destroy()”来销毁当前标签,但它返回

AttributeError: '_tkinter.tkapp' object has no attribute 'framelist'

下面是新的“createSystem”函数的代码:

def createSystem(self, event):

        if self.labelCombo.get() == "zxcv":
            for i, labelname in zip(range(len(bbbbList)),bbbbList):
                root.add_frame()
                #labellist.append(tk.Frame(root))
                ttk.Label(framelist[i], text = labelname).grid()
                ttk.Combobox(self, width = 10, state = 'readonly', values = bbbbList.get(labelname)).grid(column = 1, row = i + 1)



        if self.labelCombo.get() == "qeqL":
            for i, labelname in zip(range(len(aaaaLabelList)),aaaaLabelList):  
                ttk.Label(self, text = labelname + ":     ").grid(column = 0, row = list(aaaaLabelList).index(labelname) + 2) 
                ttk.Combobox(self, width = 10, state = 'readonly', values = aaaaLabelList.get(labelname)).grid(column = 1, row = list(aaaaLabelList).index(labelname) + 2)

Tags: selfgetdefcolumnroot标签listgrid
2条回答

主要问题是在创建新的小部件之前没有销毁以前的小部件(因此重叠)。我已经使你的代码满足你的需要(希望如此)。 希望这会有帮助

    def delete_frames(self):
        # By using [2:] we are sparing the first combobox
        # Though I recommend creating these comboboxes in seperate frame
        if self.winfo_children()[2:] != []:
            for widget in self.winfo_children()[2:]:
                widget.destroy()
                # Fully Removing by calling destroy can also use hide
    def createSystem(self, event):
        self.delete_frames()
        to_use = bbbbList if self.labelCombo.get() == "zxcv" else aaaaLabelList
        global framelist
        i = 1
        for item in to_use.items():
            tk.Label(self, text=item[0]).grid(column=0, row=i)
            ttk.Combobox(self, width=10, state='readonly',
                         values=item[1]).grid(column=1, row=i)
            i += 1

最好先在InitUI(...)中的单个帧内创建label+combo列表(aaaaListbbbbLabelList),然后在createSystem(...)中的帧之间切换。你知道吗

下面是修改后的InitUI()createSystem()

def createSystem(self, event):
    # get the frame based on selection of labelCombo
    frame = self.frames[self.labelCombo.get()]
    # show the frame
    frame.grid(row=1, column=0, columnspan=2, sticky='nsew')
    frame.tkraise()

def InitUI(self):
    self.label_1 = ttk.Label(self,text = "asss dddd:    ")
    self.label_1.grid(column = 0, row = 0)

    self.labelCombo = ttk.Combobox(self, width = 5, state = 'readonly', values = list(cc_category.keys()))
    self.labelCombo.bind('<<ComboboxSelected>>', self.createSystem)
    self.labelCombo.grid(column = 1, row = 0)

    self.frames = {} # hold the frames containing the label+combo list
    self.comboboxes = {} # hold the comboboxes in the frames
    for category in cc_category.keys():
        frame = tk.Frame(self)
        selectedList = bbbbList if category == "zxcv" else aaaaLabelList
        for row, labelname in enumerate(selectedList):
            ttk.Label(frame, text=labelname+":     ").grid(column=0, row=row) 
            combobox = ttk.Combobox(frame, width=10, state='readonly', values=selectedList.get(labelname))
            combobox.grid(column=1, row=row)
            self.comboboxes[labelname] = combobox
        self.frames[category] = frame

相关问题 更多 >