Tkinter python 3循环中循环的复选框重叠网格

2024-06-02 07:31:54 发布

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

我这里有一段代码,它运行的窗口如下所示:

Original WIndow

单击其中一个元素按钮后,我得到如下同位素结果:

Results with many isotopes

但如果我选择另一个按钮,我只会覆盖此处显示的复选框: Overwritten results not refreshed frame

在显示结果之前,我无法找到一种方法来销毁之前的复选框。我已经尝试了很多方法,我非常确定这里的SO post就是答案,但我不能100%确定是否需要将结果划分为一个范围,并相应地附加按钮列表。我正在尝试,但我对前端编程还不熟悉。有人知道如何让这东西工作吗

代码如下:

import tkinter as tk
from tkinter import ttk
import os
import pandas as pd

__location__ = os.path.realpath(
    os.path.join(os.getcwd(), os.path.dirname(__file__)))


class AppTBL(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.winfo_toplevel().title("Periodic Table of the Elements")
        self.topLabel = tk.Label(
            self, text="\n\n\n\nClick the element you would like information about.", font=20)
        self.topLabel.grid(row=0, column=0, columnspan=18)
        self.column1 = [
            ('H', 'Hydrogen', '\nAtomic # = 1\nAtomic Weight =1.01\nState = Gas\nCategory = Alkali Metals',),
            ('Li', 'Lithium', '\nAtomic # = 3\nAtomic Weight = 6.94\nState = Solid\nCategory = Alkali Metals'),
            ('Sod', 'Sodium', '\nAtomic # = 11\nAtomic Weight = 22.99\nState = Solid\nCategory = Alkali Metals'),
            ('K', 'Potassium', '\nAtomic # = 19\nAtomic Weight = 39.10\nState = Solid\nCategory = Alkali Metals'),
            ('Rb', 'Rubidium', '\nAtomic # = 37\nAtomic Weight = 85.47\nState = Solid\nCategory = Alkali Metals'),
            ('Cs', 'Cesium', '\nAtomic # = 55\nAtomic Weight = 132.91\nState = Solid\nCategory = Alkali Metals'),
            ('Fr', 'Francium', '\nAtomic # = 87\nAtomic Weight = 223.00\nState = Solid\nCategory = Alkali Metals')]
        r = 1
        c = 0
        for b in self.column1:
            self.elebtn = tk.Button(self,
                                    text=b[0],
                                    width=5,
                                    height=2,
                                    bg="grey",
                                    command=lambda text=b: [self.name(text[1]), self.thebtn(text[1]), self.isotopes(text[0]), self.isodestroy]).grid(row=r, column=c)
            r += 1
            if r > len(self.column1):
                r = 1
                c += 1
        self.infoLine = tk.Label(self, text="", justify='left')
        self.infoLine.grid(row=1, column=3, columnspan=10, rowspan=4)

    def name(self, text):
        self.topLabel.config(text=text)

    def info(self, text):
        self.infoLine.config(text=text)

    def thebtn(self, anything):
        thefile = os.path.join(__location__, 'thefile.txt')
        elementStr = []
        elementStr.append(anything)
        with open(thefile, 'w') as writeit:
            for each in elementStr:
                writeit.write(each)

    def isotopes(self, text):
        isofile = os.path.join(__location__, 'isotope.csv')
        text = text
        df = pd.read_csv(isofile, header=0)
        subset = df[df['element'] == text.upper()]
        subset = subset.astype({'isotope': int})
        subindex = subset.index
        numrows = len(subindex)
        r = 1
        c = 2
        r1 = 1
        c1 = 2
        for index, row in subset.iterrows():
            if numrows < 7:
                text = row['isotope']
                isobtn = tk.Checkbutton(self, text=text, width=3,
                                        height=1, fg='brown').grid(row=r, column=c)
                r += 1
                if r > len(self.column1):
                    r = 1
                    c += 1
            elif numrows >= 7:
                text = row['isotope']
                chkbtn = tk.Checkbutton(self, text=text, width=3,
                                        height=1, fg='brown').grid(row=r1, column=c1)
                r1 += 1
                if r1 > len(self.column1):
                    r1 = 1
                    c1 += 1

    def isodestroy(self):
        pass


def endit(gui_sys):
    # self.element_table_callback()
    pass


root = tk.Tk()
root.eval('tk::PlaceWindow . center')
a = AppTBL(root)
a.grid(row=0, column=0, sticky='nsew')
a.bind('<Destroy>', endit)
a.bind('<Button-1>', AppTBL.isodestroy)
a.mainloop()

提前谢谢!我已经被困在这个问题上两天了,我只是在这里失去理智

for isotopes.csv it will not work if you copy and paste code unless you add a csv file in the same directory.. here is a little bit for example if needed. You will need to turn it into a csv in notepad++ or notepad. I can also give the original file in a share drive if needed.

^{tb1}$

答案是:

        for child in self.winfo_children():
        if child.winfo_class() == 'Checkbutton':
            child.destroy()

但这也包括从运行中获取结果,将其附加到数据库中自己的表中。然后在另一个我必须运行两次的函数中再次调用它。单击按钮之前和之后各一次


Tags: textinselfifosdeftkgrid
1条回答
网友
1楼 · 发布于 2024-06-02 07:31:54

如果要在显示下一个元素的结果之前删除前面的复选框,则有这样一个选项。 小部件有一个方法来获取其所有子部件的列表widget.winfo_children()。 可以为复选框(如框架)创建容器。如有必要,移除框架中的所有元件

要了解其工作原理,可以执行以下操作:

def __init__


def __init__(self, parent, *args, **kwargs):
    ...
    # self.infoLine = tk.Label(self, text="", justify='left')
    # self.infoLine.grid(row=1, column=3, columnspan=10, rowspan=4)
    self.frame = tk.Frame(self)
    self.frame.grid(row=1, column=3, columnspan=10, rowspan=4)

def isotopes


def isotopes(self, text):
    # destroy previous checkboxes
    for child in self.frame.winfo_children():
        child.destroy()
    ...
    for index, row in subset.iterrows():
        ...
            isobtn = tk.Checkbutton(self.frame, ...
        ...
            chkbtn = tk.Checkbutton(self.frame, ...

您可能需要重新设计界面,以使框架适合窗口

相关问题 更多 >