【问题标题】:Tkinter - python 3 - overlapping grid of checkboxes from a loop within a loopTkinter - python 3 - 循环内循环中的复选框重叠网格
【发布时间】:2021-10-17 03:15:26
【问题描述】:

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

单击其中一个元素按钮后,我会得到此处显示的同位素结果:

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

我终其一生都无法在显示结果之前找到一种方法来销毁以前的复选框。我尝试了多种方法,我很确定这里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()

提前致谢!我已经坚持了两天了,我只是在这里失去理智。

对于 isotopes.csv,如果您复制和粘贴代码,它将不起作用,除非您在同一目录中添加 csv 文件。如果需要,这里有一些示例。您需要在记事本++ 或记事本中将其转换为 csv。如果需要,我也可以在共享驱动器中提供原始文件。

element isotope
H 1
H 2
H 3
H 5
H 6
H 7
HE 10
HE 2
HE 3
HE 4
HE 5
HE 6
HE 7
HE 8
HE 9

答案是:

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

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

【问题讨论】:

    标签: python pandas loops tkinter python-class


    【解决方案1】:

    如果您想在显示下一个元素的结果之前删除前面的复选框,那么有这样一个选项。 一个小部件有一个方法来获取它的所有孩子的列表,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, ...
    
    

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

    【讨论】:

    • 目前不起作用,但我将尝试创建另一个框架,它可能适合并在框架中包含一个框架。
    • 这似乎根本不起作用。我可以看到列表,上面有一个框架,但它仍然在下面显示以前的网格。但是,我确实删除了 self.infoline 部分的想法,因为它根本不再被使用,所以我希望我越来越近了。
    • 无论我做什么,新框架都不会使用与原始框架相同的网格布局。如果有帮助,我可以上传主程序的代码,因为它连接到 sqlite db 以获取所有元素。但是,如果您复制并粘贴它,它将不会在您的编辑器中运行。
    • 对我来说正确答案是:对于 self.winfo_children() 中的孩子:if child.winfo_class() == 'Checkbutton': child.destroy()
    • 如果除了要删除的复选框之外没有其他复选框,则可以将窗口中的所有复选框都删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    相关资源
    最近更新 更多